diff --git a/include/boost/variant2/expected.hpp b/include/boost/variant2/expected.hpp index f6651f3..fb90ea1 100644 --- a/include/boost/variant2/expected.hpp +++ b/include/boost/variant2/expected.hpp @@ -30,7 +30,9 @@ template using unexpected_ = variant; // bad_expected_access -class bad_expected_access: public std::exception +template class bad_expected_access; + +template<> class bad_expected_access: public std::exception { private: @@ -42,21 +44,62 @@ public: { } - template explicit bad_expected_access( mp_identity ) noexcept: msg_( "bad_expected_access: " + boost::core::demangle( typeid(E).name() ) ) + explicit bad_expected_access( std::string&& msg ) noexcept: msg_( std::move(msg) ) // extension { } char const * what() const noexcept { - return msg_.empty()? "bad_expected_access": msg_.c_str(); + return msg_.empty()? "bad_expected_access<>": msg_.c_str(); + } +}; + +namespace detail +{ + +template::value>> std::string add_value( E const& /*e*/ ) +{ + return std::string(); +} + +template::value>> std::string add_value( E const& e ) +{ + return ": " + std::to_string( static_cast(e) ); +} + +} // namespace detail + +template class bad_expected_access: public bad_expected_access +{ +private: + + E e_; + +public: + + explicit bad_expected_access( E const& e ) + noexcept( std::is_nothrow_copy_constructible::value ) + : bad_expected_access( "bad_expected_access<" + boost::core::demangle( typeid(E).name() ) + ">" + variant2::detail::add_value( e ) ), e_( e ) + { + } + + explicit bad_expected_access( E&& e ) + noexcept( std::is_nothrow_move_constructible::value ) + : bad_expected_access( "bad_expected_access<" + boost::core::demangle( typeid(E).name() ) + ">" + variant2::detail::add_value( e ) ), e_( std::move(e) ) + { + } + + E error() const + { + return e_; } }; // expected -template void throw_on_unexpected( E const & /*e*/ ) +template void throw_on_unexpected( E const& e ) { - throw bad_expected_access( mp_identity() ); + throw bad_expected_access( e ); } void throw_on_unexpected( std::error_code const & e ) @@ -72,7 +115,7 @@ void throw_on_unexpected( std::exception_ptr const & e ) } else { - throw bad_expected_access( mp_identity() ); + throw bad_expected_access<>( "bad_expected_access<>: null exception_ptr" ); } } @@ -90,7 +133,7 @@ private: { if( I == 0 ) { - throw bad_expected_access( mp_identity() ); + throw bad_expected_access<>( "bad_expected_access<>: value present on error request" ); } else {