@@ -279,6 +279,7 @@ inline namespace bitwizeshift {
279279 template <typename , typename >
280280 class result ;
281281
282+ template <typename >
282283 class bad_result_access ;
283284
284285 // ===========================================================================
@@ -315,28 +316,52 @@ inline namespace bitwizeshift {
315316#if !defined(RESULT_DISABLE_EXCEPTIONS)
316317
317318 // ===========================================================================
318- // class : bad_result_access
319+ // class : bad_result_access<E>
319320 // ===========================================================================
320321
321322 // ///////////////////////////////////////////////////////////////////////////
322323 // / \brief An exception thrown when result::value is accessed without
323324 // / a contained value
324325 // ///////////////////////////////////////////////////////////////////////////
326+ template <typename E>
325327 class bad_result_access : public std ::logic_error
326328 {
327329 // -------------------------------------------------------------------------
328330 // Constructor / Assignment
329331 // -------------------------------------------------------------------------
330332 public:
331333
332- bad_result_access ();
334+ // / \brief Constructs this exception using the underlying error type for
335+ // / the error type
336+ // /
337+ // / \param error the underlying error
338+ template <typename E2 ,
339+ typename = typename std::enable_if<std::is_constructible<E,E2 >::value>::type>
340+ explicit bad_result_access (E2 && error);
333341 bad_result_access (const bad_result_access& other) = default ;
334342 bad_result_access (bad_result_access&& other) = default ;
335343
336344 // -------------------------------------------------------------------------
337345
338346 auto operator =(const bad_result_access& other) -> bad_result_access& = default ;
339347 auto operator =(bad_result_access&& other) -> bad_result_access& = default ;
348+
349+ // / \{
350+ // / \brief Gets the underlying error
351+ // /
352+ // / \return the error
353+ auto error () & noexcept -> E&;
354+ auto error () && noexcept -> E&&;
355+ auto error () const & noexcept -> const E&;
356+ auto error () const && noexcept -> const E&&;
357+ // / \}
358+
359+ // -------------------------------------------------------------------------
360+ // Private Members
361+ // -------------------------------------------------------------------------
362+ private:
363+
364+ E m_error;
340365 };
341366
342367#endif
@@ -1370,8 +1395,9 @@ inline namespace bitwizeshift {
13701395 template <typename T, typename E>
13711396 constexpr auto extract_error (const result<T,E>& exp) noexcept -> const E&;
13721397
1398+ template <typename E>
13731399 [[noreturn]]
1374- auto throw_bad_result_access () -> void;
1400+ auto throw_bad_result_access (E&& error ) -> void;
13751401
13761402 } // namespace detail
13771403
@@ -2452,10 +2478,13 @@ inline namespace bitwizeshift {
24522478
24532479 // -------------------------------------------------------------------------
24542480
2481+ // / \{
24552482 // / \brief Throws an exception if contains an error
24562483 // /
24572484 // / \throws bad_result_access if `*this` contains an error.
2458- RESULT_CPP14_CONSTEXPR auto value () const -> void;
2485+ RESULT_CPP14_CONSTEXPR auto value () && -> void;
2486+ RESULT_CPP14_CONSTEXPR auto value () const & -> void;
2487+ // / \}
24592488
24602489 // / \{
24612490 // / \brief Returns the contained error, if one exists, or a
@@ -2815,11 +2844,50 @@ namespace std {
28152844// Constructors
28162845// -----------------------------------------------------------------------------
28172846
2847+ template <typename E>
2848+ template <typename E2 , typename >
2849+ inline RESULT_INLINE_VISIBILITY
2850+ RESULT_NS_IMPL ::bad_result_access<E>::bad_result_access(E2 && error)
2851+ : logic_error{" error attempting to access value from result containing error" },
2852+ m_error (detail::forward<E2 >(error))
2853+ {
2854+
2855+ }
2856+
2857+ // -----------------------------------------------------------------------------
2858+ // Observers
2859+ // -----------------------------------------------------------------------------
2860+
2861+ template <typename E>
2862+ inline RESULT_INLINE_VISIBILITY
2863+ auto RESULT_NS_IMPL ::bad_result_access<E>::error()
2864+ & noexcept -> E&
2865+ {
2866+ return m_error;
2867+ }
2868+
2869+ template <typename E>
28182870inline RESULT_INLINE_VISIBILITY
2819- RESULT_NS_IMPL ::bad_result_access::bad_result_access ()
2820- : logic_error{ " bad_result_access " }
2871+ auto RESULT_NS_IMPL ::bad_result_access<E>::error ()
2872+ && noexcept -> E&&
28212873{
2874+ return static_cast <E&&>(m_error);
2875+ }
28222876
2877+ template <typename E>
2878+ inline RESULT_INLINE_VISIBILITY
2879+ auto RESULT_NS_IMPL ::bad_result_access<E>::error()
2880+ const & noexcept -> const E&
2881+ {
2882+ return m_error;
2883+ }
2884+
2885+ template <typename E>
2886+ inline RESULT_INLINE_VISIBILITY
2887+ auto RESULT_NS_IMPL ::bad_result_access<E>::error()
2888+ const && noexcept -> const E&&
2889+ {
2890+ return static_cast <const E&&>(m_error);
28232891}
28242892
28252893#endif
@@ -3531,14 +3599,23 @@ auto RESULT_NS_IMPL::detail::extract_error(const result<T,E>& exp) noexcept -> c
35313599 return result_error_extractor::get (exp);
35323600}
35333601
3602+ template <typename E>
35343603[[noreturn]]
35353604inline RESULT_INLINE_VISIBILITY
3536- auto RESULT_NS_IMPL::detail::throw_bad_result_access () -> void
3605+ auto RESULT_NS_IMPL::detail::throw_bad_result_access (E&& error ) -> void
35373606{
35383607#if defined(RESULT_DISABLE_EXCEPTIONS)
35393608 std::abort ();
35403609#else
3541- throw bad_result_access{};
3610+ using exception_type = bad_result_access<
3611+ typename std::remove_const<
3612+ typename std::remove_reference<E>::type
3613+ >::type
3614+ >;
3615+
3616+ throw exception_type{
3617+ detail::forward<E>(error)
3618+ };
35423619#endif
35433620}
35443621
@@ -3868,7 +3945,8 @@ inline RESULT_INLINE_VISIBILITY RESULT_CPP14_CONSTEXPR
38683945auto RESULT_NS_IMPL ::result<T,E>::value()
38693946 & -> typename std::add_lvalue_reference<T>::type
38703947{
3871- return (has_value () || (detail::throw_bad_result_access (), false ),
3948+ return (has_value () ||
3949+ (detail::throw_bad_result_access (m_storage.storage .m_error ), false ),
38723950 m_storage.storage .m_value
38733951 );
38743952}
@@ -3880,7 +3958,8 @@ auto RESULT_NS_IMPL::result<T,E>::value()
38803958{
38813959 using reference = typename std::add_rvalue_reference<T>::type;
38823960
3883- return (has_value () || (detail::throw_bad_result_access (), true ),
3961+ return (has_value () ||
3962+ (detail::throw_bad_result_access (static_cast <E&&>(m_storage.storage .m_error )), true ),
38843963 static_cast <reference>(m_storage.storage .m_value )
38853964 );
38863965}
@@ -3890,7 +3969,8 @@ inline RESULT_INLINE_VISIBILITY constexpr
38903969auto RESULT_NS_IMPL ::result<T,E>::value()
38913970 const & -> typename std::add_lvalue_reference<typename std::add_const<T>::type>::type
38923971{
3893- return (has_value () || (detail::throw_bad_result_access (), true ),
3972+ return (has_value () ||
3973+ (detail::throw_bad_result_access (m_storage.storage .m_error ), true ),
38943974 m_storage.storage .m_value
38953975 );
38963976}
@@ -3902,7 +3982,8 @@ auto RESULT_NS_IMPL::result<T,E>::value()
39023982{
39033983 using reference = typename std::add_rvalue_reference<typename std::add_const<T>::type>::type;
39043984
3905- return (has_value () || (detail::throw_bad_result_access (), true ),
3985+ return (has_value () ||
3986+ (detail::throw_bad_result_access (static_cast <const E&&>(m_storage.storage .m_error )), true ),
39063987 (static_cast <reference>(m_storage.storage .m_value ))
39073988 );
39083989}
@@ -4364,9 +4445,23 @@ auto RESULT_NS_IMPL::result<void, E>::has_error()
43644445template <typename E>
43654446inline RESULT_INLINE_VISIBILITY RESULT_CPP14_CONSTEXPR
43664447auto RESULT_NS_IMPL ::result<void , E>::value()
4367- const -> void
4448+ const & -> void
43684449{
4369- static_cast <void >(has_value () || (detail::throw_bad_result_access (), true ));
4450+ static_cast <void >(
4451+ has_value () ||
4452+ (detail::throw_bad_result_access (m_storage.storage .m_error ), true )
4453+ );
4454+ }
4455+
4456+ template <typename E>
4457+ inline RESULT_INLINE_VISIBILITY RESULT_CPP14_CONSTEXPR
4458+ auto RESULT_NS_IMPL ::result<void , E>::value()
4459+ && -> void
4460+ {
4461+ static_cast <void >(
4462+ has_value () ||
4463+ (detail::throw_bad_result_access (static_cast <E&&>(m_storage.storage .m_error )), true )
4464+ );
43704465}
43714466
43724467template <typename E>
0 commit comments