?????????? ????????? - ??????????????? - /home/agenciai/public_html/cd38d8/outcome.tar
???????
boost_outcome.hpp 0000644 00000004567 15125552774 0010167 0 ustar 00 /* A less simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BOOST_OUTCOME_HPP #define BOOST_OUTCOME_BOOST_OUTCOME_HPP #include "std_outcome.hpp" #include "boost_result.hpp" #ifndef BOOST_SYSTEM_BASIC_OUTCOME_FAILURE_EXCEPTION_FROM_ERROR #define BOOST_SYSTEM_BASIC_OUTCOME_FAILURE_EXCEPTION_FROM_ERROR namespace boost { namespace system { // Implement the .failure() observer. inline boost::exception_ptr basic_outcome_failure_exception_from_error(const boost::system::error_code &ec) { return boost::copy_exception(boost::system::system_error(ec)); } } // namespace system } // namespace boost #endif BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S = boost::system::error_code, class P = boost::exception_ptr, class NoValuePolicy = policy::default_policy<R, S, P>> // using boost_outcome = basic_outcome<R, S, P, NoValuePolicy>; BOOST_OUTCOME_V2_NAMESPACE_END #endif trait.hpp 0000644 00000013150 15125552774 0006415 0 ustar 00 /* Traits for Outcome (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (8 commits) File Created: March 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_TRAIT_HPP #define BOOST_OUTCOME_TRAIT_HPP #include "config.hpp" BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace trait { /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R> // static constexpr bool type_can_be_used_in_basic_result = // (!std::is_reference<R>::value // && !BOOST_OUTCOME_V2_NAMESPACE::detail::is_in_place_type_t<std::decay_t<R>>::value // && !is_success_type<R> // && !is_failure_type<R> // && !std::is_array<R>::value // && (std::is_void<R>::value || (std::is_object<R>::value // && std::is_destructible<R>::value)) // ); /*! AWAITING HUGO JSON CONVERSION TOOL type definition is_error_type. Potential doc page: NOT FOUND */ template <class E> struct is_error_type { static constexpr bool value = false; }; /*! AWAITING HUGO JSON CONVERSION TOOL type definition is_error_type_enum. Potential doc page: NOT FOUND */ template <class E, class Enum> struct is_error_type_enum { static constexpr bool value = false; }; namespace detail { template <class T> using devoid = BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<T>; template <class T> std::add_rvalue_reference_t<devoid<T>> declval() noexcept; // From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf namespace detector_impl { template <class...> using void_t = void; template <class Default, class, template <class...> class Op, class... Args> struct detector { static constexpr bool value = false; using type = Default; }; template <class Default, template <class...> class Op, class... Args> struct detector<Default, void_t<Op<Args...>>, Op, Args...> { static constexpr bool value = true; using type = Op<Args...>; }; } // namespace detector_impl template <template <class...> class Op, class... Args> using is_detected = detector_impl::detector<void, void, Op, Args...>; template <class Arg> using result_of_make_error_code = decltype(make_error_code(declval<Arg>())); template <class Arg> using introspect_make_error_code = is_detected<result_of_make_error_code, Arg>; template <class Arg> using result_of_make_exception_ptr = decltype(make_exception_ptr(declval<Arg>())); template <class Arg> using introspect_make_exception_ptr = is_detected<result_of_make_exception_ptr, Arg>; template <class T> struct _is_error_code_available { static constexpr bool value = detail::introspect_make_error_code<T>::value; using type = typename detail::introspect_make_error_code<T>::type; }; template <class T> struct _is_exception_ptr_available { static constexpr bool value = detail::introspect_make_exception_ptr<T>::value; using type = typename detail::introspect_make_exception_ptr<T>::type; }; } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL type definition is_error_code_available. Potential doc page: NOT FOUND */ template <class T> struct is_error_code_available { static constexpr bool value = detail::_is_error_code_available<std::decay_t<T>>::value; using type = typename detail::_is_error_code_available<std::decay_t<T>>::type; }; template <class T> constexpr bool is_error_code_available_v = detail::_is_error_code_available<std::decay_t<T>>::value; /*! AWAITING HUGO JSON CONVERSION TOOL type definition is_exception_ptr_available. Potential doc page: NOT FOUND */ template <class T> struct is_exception_ptr_available { static constexpr bool value = detail::_is_exception_ptr_available<std::decay_t<T>>::value; using type = typename detail::_is_exception_ptr_available<std::decay_t<T>>::type; }; template <class T> constexpr bool is_exception_ptr_available_v = detail::_is_exception_ptr_available<std::decay_t<T>>::value; } // namespace trait BOOST_OUTCOME_V2_NAMESPACE_END #endif basic_outcome.hpp 0000644 00000166525 15125552774 0010125 0 ustar 00 /* A less simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (20 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_OUTCOME_HPP #define BOOST_OUTCOME_BASIC_OUTCOME_HPP #include "config.hpp" #include "basic_result.hpp" #include "detail/basic_outcome_exception_observers.hpp" #include "detail/basic_outcome_failure_observers.hpp" #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang #endif BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN template <class R, class S, class P, class NoValuePolicy> // class basic_outcome; namespace detail { // May be reused by basic_outcome subclasses to save load on the compiler template <class value_type, class error_type, class exception_type> struct outcome_predicates { using result = result_predicates<value_type, error_type>; // Predicate for the implicit constructors to be available static constexpr bool implicit_constructors_enabled = // result::implicit_constructors_enabled // && !detail::is_implicitly_constructible<value_type, exception_type> // && !detail::is_implicitly_constructible<error_type, exception_type> // && !detail::is_implicitly_constructible<exception_type, value_type> // && !detail::is_implicitly_constructible<exception_type, error_type>; // Predicate for the value converting constructor to be available. template <class T> static constexpr bool enable_value_converting_constructor = // implicit_constructors_enabled // &&result::template enable_value_converting_constructor<T> // && !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition // Predicate for the error converting constructor to be available. template <class T> static constexpr bool enable_error_converting_constructor = // implicit_constructors_enabled // &&result::template enable_error_converting_constructor<T> // && !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition // Predicate for the error condition converting constructor to be available. template <class ErrorCondEnum> static constexpr bool enable_error_condition_converting_constructor = result::template enable_error_condition_converting_constructor<ErrorCondEnum> // && !detail::is_implicitly_constructible<exception_type, ErrorCondEnum>; // Predicate for the exception converting constructor to be available. template <class T> static constexpr bool enable_exception_converting_constructor = // implicit_constructors_enabled // && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction && !detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T> && detail::is_implicitly_constructible<exception_type, T>; // Predicate for the error + exception converting constructor to be available. template <class T, class U> static constexpr bool enable_error_exception_converting_constructor = // implicit_constructors_enabled // && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction && !detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T> // && !detail::is_implicitly_constructible<value_type, U> && detail::is_implicitly_constructible<exception_type, U>; // Predicate for the converting copy constructor from a compatible outcome to be available. template <class T, class U, class V, class W> static constexpr bool enable_compatible_conversion = // (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // if our value types are constructible &&(std::is_void<U>::value || detail::is_explicitly_constructible<error_type, typename basic_outcome<T, U, V, W>::error_type>) // if our error types are constructible &&(std::is_void<V>::value || detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>) // if our exception types are constructible ; // Predicate for the converting constructor from a make_error_code() of the input to be available. template <class T, class U, class V, class W> static constexpr bool enable_make_error_code_compatible_conversion = // trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code && !enable_compatible_conversion<T, U, V, W> // and the normal compatible conversion is not available && (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // and if our value types are constructible &&detail::is_explicitly_constructible<error_type, typename trait::is_error_code_available<U>::type> // and our error type is constructible from a make_error_code() && (std::is_void<V>::value || detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>); // and our exception types are constructible // Predicate for the implicit converting inplace constructor from a compatible input to be available. struct disable_inplace_value_error_exception_constructor; template <class... Args> using choose_inplace_value_error_exception_constructor = std::conditional_t< // ((static_cast<int>(detail::is_constructible<value_type, Args...>) + static_cast<int>(detail::is_constructible<error_type, Args...>) + static_cast<int>(detail::is_constructible<exception_type, Args...>)) > 1), // disable_inplace_value_error_exception_constructor, // std::conditional_t< // detail::is_constructible<value_type, Args...>, // value_type, // std::conditional_t< // detail::is_constructible<error_type, Args...>, // error_type, // std::conditional_t< // detail::is_constructible<exception_type, Args...>, // exception_type, // disable_inplace_value_error_exception_constructor>>>>; template <class... Args> static constexpr bool enable_inplace_value_error_exception_constructor = // implicit_constructors_enabled && !std::is_same<choose_inplace_value_error_exception_constructor<Args...>, disable_inplace_value_error_exception_constructor>::value; }; // Select whether to use basic_outcome_failure_observers or not template <class Base, class R, class S, class P, class NoValuePolicy> using select_basic_outcome_failure_observers = // std::conditional_t<trait::is_error_code_available<S>::value && trait::is_exception_ptr_available<P>::value, basic_outcome_failure_observers<Base, R, S, P, NoValuePolicy>, Base>; template <class T, class U, class V> constexpr inline const V &extract_exception_from_failure(const failure_type<U, V> &v) { return v.exception(); } template <class T, class U, class V> constexpr inline V &&extract_exception_from_failure(failure_type<U, V> &&v) { return static_cast<failure_type<U, V> &&>(v).exception(); } template <class T, class U> constexpr inline const U &extract_exception_from_failure(const failure_type<U, void> &v) { return v.error(); } template <class T, class U> constexpr inline U &&extract_exception_from_failure(failure_type<U, void> &&v) { return static_cast<failure_type<U, void> &&>(v).error(); } template <class T> struct is_basic_outcome { static constexpr bool value = false; }; template <class R, class S, class T, class N> struct is_basic_outcome<basic_outcome<R, S, T, N>> { static constexpr bool value = true; }; } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL type alias template <class T> is_basic_outcome. Potential doc page: `is_basic_outcome<T>` */ template <class T> using is_basic_outcome = detail::is_basic_outcome<std::decay_t<T>>; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> static constexpr bool is_basic_outcome_v = detail::is_basic_outcome<std::decay_t<T>>::value; namespace concepts { #if defined(__cpp_concepts) /* The `basic_outcome` concept. \requires That `U` matches a `basic_outcome`. */ template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL basic_outcome = BOOST_OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value || (requires(U v) { BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>(v); } && // detail::convertible< U, BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>> && // detail::base_of< BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>, U>); #else namespace detail { inline no_match match_basic_outcome(...); template <class R, class S, class P, class NVP, class T, // typename = typename T::value_type, // typename = typename T::error_type, // typename = typename T::exception_type, // typename = typename T::no_value_policy_type, // typename std::enable_if_t<std::is_convertible<T, BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>>::value && // std::is_base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>, T>::value, bool> = true> inline BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> match_basic_outcome(BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> &&, T &&); template <class U> static constexpr bool basic_outcome = BOOST_OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value || !std::is_same<no_match, decltype(match_basic_outcome(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>(), std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; } // namespace detail /* The `basic_outcome` concept. \requires That `U` matches a `basic_outcome`. */ template <class U> static constexpr bool basic_outcome = detail::basic_outcome<U>; #endif } // namespace concepts namespace hooks { /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class... U> constexpr inline void hook_outcome_construction(T * /*unused*/, U &&... /*unused*/) noexcept {} /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U> constexpr inline void hook_outcome_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {} /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U> constexpr inline void hook_outcome_move_construction(T * /*unused*/, U && /*unused*/) noexcept {} /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U, class... Args> constexpr inline void hook_outcome_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept { } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class P, class NoValuePolicy, class U> constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept; } // namespace hooks /*! AWAITING HUGO JSON CONVERSION TOOL type definition template <class R, class S, class P, class NoValuePolicy> basic_outcome. Potential doc page: `basic_outcome<T, EC, EP, NoValuePolicy>` */ template <class R, class S, class P, class NoValuePolicy> // class BOOST_OUTCOME_NODISCARD basic_outcome #if defined(BOOST_OUTCOME_DOXYGEN_IS_IN_THE_HOUSE) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) : public detail::basic_outcome_failure_observers<detail::basic_result_final<R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>, public detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, public detail::basic_result_final<R, S, NoValuePolicy> #else : public detail::select_basic_outcome_failure_observers< detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy> #endif { static_assert(trait::type_can_be_used_in_basic_result<P>, "The exception_type cannot be used"); static_assert(std::is_void<P>::value || std::is_default_constructible<P>::value, "exception_type must be void or default constructible"); using base = detail::select_basic_outcome_failure_observers< detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>; friend struct policy::base; template <class T, class U, class V, class W> // friend class basic_outcome; template <class T, class U, class V, class W, class X> friend constexpr inline void hooks::override_outcome_exception(basic_outcome<T, U, V, W> *o, X &&v) noexcept; // NOLINT struct implicit_constructors_disabled_tag { }; struct value_converting_constructor_tag { }; struct error_converting_constructor_tag { }; struct error_condition_converting_constructor_tag { }; struct exception_converting_constructor_tag { }; struct error_exception_converting_constructor_tag { }; struct explicit_valueorerror_converting_constructor_tag { }; struct explicit_compatible_copy_conversion_tag { }; struct explicit_compatible_move_conversion_tag { }; struct explicit_make_error_code_compatible_copy_conversion_tag { }; struct explicit_make_error_code_compatible_move_conversion_tag { }; struct error_failure_tag { }; struct exception_failure_tag { }; struct disable_in_place_value_type { }; struct disable_in_place_error_type { }; struct disable_in_place_exception_type { }; public: using value_type = R; using error_type = S; using exception_type = P; using no_value_policy_type = NoValuePolicy; template <class T, class U = S, class V = P, class W = NoValuePolicy> using rebind = basic_outcome<T, U, V, W>; protected: // Requirement predicates for outcome. struct predicate { using base = detail::outcome_predicates<value_type, error_type, exception_type>; // Predicate for any constructors to be available at all static constexpr bool constructors_enabled = (!std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value || (std::is_void<value_type>::value && std::is_void<error_type>::value)) // && (!std::is_same<std::decay_t<value_type>, std::decay_t<exception_type>>::value || (std::is_void<value_type>::value && std::is_void<exception_type>::value)) // && (!std::is_same<std::decay_t<error_type>, std::decay_t<exception_type>>::value || (std::is_void<error_type>::value && std::is_void<exception_type>::value)) // ; // Predicate for implicit constructors to be available at all static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled; // Predicate for the value converting constructor to be available. template <class T> static constexpr bool enable_value_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type && base::template enable_value_converting_constructor<T>; // Predicate for the error converting constructor to be available. template <class T> static constexpr bool enable_error_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type && base::template enable_error_converting_constructor<T>; // Predicate for the error condition converting constructor to be available. template <class ErrorCondEnum> static constexpr bool enable_error_condition_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<ErrorCondEnum>, basic_outcome>::value // not my type && base::template enable_error_condition_converting_constructor<ErrorCondEnum>; // Predicate for the exception converting constructor to be available. template <class T> static constexpr bool enable_exception_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type && base::template enable_exception_converting_constructor<T>; // Predicate for the error + exception converting constructor to be available. template <class T, class U> static constexpr bool enable_error_exception_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type && base::template enable_error_exception_converting_constructor<T, U>; // Predicate for the converting constructor from a compatible input to be available. template <class T, class U, class V, class W> static constexpr bool enable_compatible_conversion = // constructors_enabled // && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type && base::template enable_compatible_conversion<T, U, V, W>; // Predicate for the converting constructor from a make_error_code() of the input to be available. template <class T, class U, class V, class W> static constexpr bool enable_make_error_code_compatible_conversion = // constructors_enabled // && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type && base::template enable_make_error_code_compatible_conversion<T, U, V, W>; // Predicate for the inplace construction of value to be available. template <class... Args> static constexpr bool enable_inplace_value_constructor = // constructors_enabled // && (std::is_void<value_type>::value // || detail::is_constructible<value_type, Args...>); // Predicate for the inplace construction of error to be available. template <class... Args> static constexpr bool enable_inplace_error_constructor = // constructors_enabled // && (std::is_void<error_type>::value // || detail::is_constructible<error_type, Args...>); // Predicate for the inplace construction of exception to be available. template <class... Args> static constexpr bool enable_inplace_exception_constructor = // constructors_enabled // && (std::is_void<exception_type>::value // || detail::is_constructible<exception_type, Args...>); // Predicate for the implicit converting inplace constructor to be available. template <class... Args> static constexpr bool enable_inplace_value_error_exception_constructor = // constructors_enabled // &&base::template enable_inplace_value_error_exception_constructor<Args...>; template <class... Args> using choose_inplace_value_error_exception_constructor = typename base::template choose_inplace_value_error_exception_constructor<Args...>; }; public: using value_type_if_enabled = std::conditional_t<std::is_same<value_type, error_type>::value || std::is_same<value_type, exception_type>::value, disable_in_place_value_type, value_type>; using error_type_if_enabled = std::conditional_t<std::is_same<error_type, value_type>::value || std::is_same<error_type, exception_type>::value, disable_in_place_error_type, error_type>; using exception_type_if_enabled = std::conditional_t<std::is_same<exception_type, value_type>::value || std::is_same<exception_type, error_type>::value, disable_in_place_exception_type, exception_type>; protected: detail::devoid<exception_type> _ptr; public: /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class Arg, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((!predicate::constructors_enabled && sizeof...(Args) >= 0))) basic_outcome(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_outcome<> with any of the same type is NOT SUPPORTED, see docs! /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled // && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T> || detail::is_implicitly_constructible<exception_type, T>) ))) basic_outcome(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) = delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs! /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>)) constexpr basic_outcome(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept( detail::is_nothrow_constructible<value_type, T>) // NOLINT : base{in_place_type<typename base::_value_type>, static_cast<T &&>(t)} , _ptr() { using namespace hooks; hook_outcome_construction(this, static_cast<T &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>)) constexpr basic_outcome(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept( detail::is_nothrow_constructible<error_type, T>) // NOLINT : base{in_place_type<typename base::_error_type>, static_cast<T &&>(t)} , _ptr() { using namespace hooks; hook_outcome_construction(this, static_cast<T &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), // BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>)) constexpr basic_outcome(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept( noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT : base{in_place_type<typename base::_error_type>, make_error_code(t)} { using namespace hooks; hook_outcome_construction(this, static_cast<ErrorCondEnum &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_exception_converting_constructor<T>)) constexpr basic_outcome(T &&t, exception_converting_constructor_tag /*unused*/ = exception_converting_constructor_tag()) noexcept( detail::is_nothrow_constructible<exception_type, T>) // NOLINT : base() , _ptr(static_cast<T &&>(t)) { using namespace hooks; this->_state._status.set_have_exception(true); hook_outcome_construction(this, static_cast<T &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_exception_converting_constructor<T, U>)) constexpr basic_outcome(T &&a, U &&b, error_exception_converting_constructor_tag /*unused*/ = error_exception_converting_constructor_tag()) noexcept( detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT : base{in_place_type<typename base::_error_type>, static_cast<T &&>(a)} , _ptr(static_cast<U &&>(b)) { using namespace hooks; this->_state._status.set_have_exception(true); hook_outcome_construction(this, static_cast<T &&>(a), static_cast<U &&>(b)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), // BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_outcome_inputs || !concepts::basic_outcome<T>), // BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_outcome, std::decay_t<T>>{}(std::declval<T>()))) constexpr explicit basic_outcome(T &&o, explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT : basic_outcome{convert::value_or_error<basic_outcome, std::decay_t<T>>{}(static_cast<T &&>(o))} { } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>)) constexpr explicit basic_outcome( const basic_outcome<T, U, V, W> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> &&detail::is_nothrow_constructible<exception_type, V>) : base{typename base::compatible_conversion_tag(), o} , _ptr(o._ptr) { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>)) constexpr explicit basic_outcome( basic_outcome<T, U, V, W> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> &&detail::is_nothrow_constructible<exception_type, V>) : base{typename base::compatible_conversion_tag(), static_cast<basic_outcome<T, U, V, W> &&>(o)} , _ptr(static_cast<typename basic_outcome<T, U, V, W>::exception_type &&>(o._ptr)) { using namespace hooks; hook_outcome_move_construction(this, static_cast<basic_outcome<T, U, V, W> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>)) constexpr explicit basic_outcome( const basic_result<T, U, V> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> &&detail::is_nothrow_constructible<exception_type>) : base{typename base::compatible_conversion_tag(), o} , _ptr() { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>)) constexpr explicit basic_outcome( basic_result<T, U, V> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> &&detail::is_nothrow_constructible<exception_type>) : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} , _ptr() { using namespace hooks; hook_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>)) constexpr explicit basic_outcome(const basic_result<T, U, V> &o, explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ = explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&noexcept(make_error_code(std::declval<U>())) && detail::is_nothrow_constructible<exception_type>) : base{typename base::make_error_code_compatible_conversion_tag(), o} , _ptr() { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>)) constexpr explicit basic_outcome(basic_result<T, U, V> &&o, explicit_make_error_code_compatible_move_conversion_tag /*unused*/ = explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&noexcept(make_error_code(std::declval<U>())) && detail::is_nothrow_constructible<exception_type>) : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} , _ptr() { using namespace hooks; hook_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>)) constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>) : base{_, static_cast<Args &&>(args)...} , _ptr() { using namespace hooks; hook_outcome_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class U, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>)) constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>) : base{_, il, static_cast<Args &&>(args)...} , _ptr() { using namespace hooks; hook_outcome_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>)) constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>) : base{_, static_cast<Args &&>(args)...} , _ptr() { using namespace hooks; hook_outcome_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class U, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>)) constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>) : base{_, il, static_cast<Args &&>(args)...} , _ptr() { using namespace hooks; hook_outcome_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<Args...>)) constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, Args...>) : base() , _ptr(static_cast<Args &&>(args)...) { using namespace hooks; this->_state._status.set_have_exception(true); hook_outcome_in_place_construction(this, in_place_type<exception_type>, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class U, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<std::initializer_list<U>, Args...>)) constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, std::initializer_list<U>, Args...>) : base() , _ptr(il, static_cast<Args &&>(args)...) { using namespace hooks; this->_state._status.set_have_exception(true); hook_outcome_in_place_construction(this, in_place_type<exception_type>, il, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_exception_constructor<A1, A2, Args...>)) constexpr basic_outcome(A1 &&a1, A2 &&a2, Args &&... args) noexcept( noexcept(typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), std::declval<Args>()...))) : basic_outcome(in_place_type<typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1), static_cast<A2 &&>(a2), static_cast<Args &&>(args)...) { } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ constexpr basic_outcome(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT : base{in_place_type<typename base::_value_type>} { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>)) constexpr basic_outcome(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(o)} { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>)) constexpr basic_outcome(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))} { using namespace hooks; hook_outcome_move_construction(this, static_cast<success_type<T> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>)) constexpr basic_outcome(const failure_type<T> &o, error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)} , _ptr() { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>)) constexpr basic_outcome(const failure_type<T> &o, exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT : base() , _ptr(detail::extract_exception_from_failure<exception_type>(o)) { this->_state._status.set_have_exception(true); using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>)) constexpr basic_outcome(const failure_type<T> &o, explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ = explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(o))} , _ptr() { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>)) constexpr basic_outcome(const failure_type<T, U> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept( detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)} , _ptr(detail::extract_exception_from_failure<exception_type>(o)) { if(!o.has_error()) { this->_state._status.set_have_error(false); } if(o.has_exception()) { this->_state._status.set_have_exception(true); } using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>)) constexpr basic_outcome(failure_type<T> &&o, error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))} , _ptr() { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>)) constexpr basic_outcome(failure_type<T> &&o, exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT : base() , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T> &&>(o))) { this->_state._status.set_have_exception(true); using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>)) constexpr basic_outcome(failure_type<T> &&o, explicit_make_error_code_compatible_move_conversion_tag /*unused*/ = explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))} , _ptr() { using namespace hooks; hook_outcome_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>)) constexpr basic_outcome(failure_type<T, U> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept( detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T, U> &&>(o))} , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T, U> &&>(o))) { if(!o.has_error()) { this->_state._status.set_have_error(false); } if(o.has_exception()) { this->_state._status.set_have_exception(true); } using namespace hooks; hook_outcome_move_construction(this, static_cast<failure_type<T, U> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ using base::operator==; using base::operator!=; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()), // BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()), // BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>())) constexpr bool operator==(const basic_outcome<T, U, V, W> &o) const noexcept( // noexcept(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()) // && noexcept(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()) // && noexcept(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>())) { if(this->_state._status.have_value() && o._state._status.have_value()) { return this->_state._value == o._state._value; // NOLINT } if(this->_state._status.have_error() && o._state._status.have_error() // && this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_error == o._error && this->_ptr == o._ptr; } if(this->_state._status.have_error() && o._state._status.have_error()) { return this->_error == o._error; } if(this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_ptr == o._ptr; } return false; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() == std::declval<T>()), // BOOST_OUTCOME_TEXPR(std::declval<exception_type>() == std::declval<U>())) constexpr bool operator==(const failure_type<T, U> &o) const noexcept( // noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>())) { if(this->_state._status.have_error() && o._state._status.have_error() // && this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_error == o.error() && this->_ptr == o.exception(); } if(this->_state._status.have_error() && o._state._status.have_error()) { return this->_error == o.error(); } if(this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_ptr == o.exception(); } return false; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()), // BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()), // BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>())) constexpr bool operator!=(const basic_outcome<T, U, V, W> &o) const noexcept( // noexcept(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()) // && noexcept(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()) // && noexcept(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>())) { if(this->_state._status.have_value() && o._state._status.have_value()) { return this->_state._value != o._state._value; // NOLINT } if(this->_state._status.have_error() && o._state._status.have_error() // && this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_error != o._error || this->_ptr != o._ptr; } if(this->_state._status.have_error() && o._state._status.have_error()) { return this->_error != o._error; } if(this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_ptr != o._ptr; } return true; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() != std::declval<T>()), // BOOST_OUTCOME_TEXPR(std::declval<exception_type>() != std::declval<U>())) constexpr bool operator!=(const failure_type<T, U> &o) const noexcept( // noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>())) { if(this->_state._status.have_error() && o._state._status.have_error() // && this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_error != o.error() || this->_ptr != o.exception(); } if(this->_state._status.have_error() && o._state._status.have_error()) { return this->_error != o.error(); } if(this->_state._status.have_exception() && o._state._status.have_exception()) { return this->_ptr != o.exception(); } return true; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ constexpr void swap(basic_outcome &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) // && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value) // && (std::is_void<exception_type>::value || detail::is_nothrow_swappable<exception_type>::value)) { #ifndef BOOST_NO_EXCEPTIONS constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value; constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value; constexpr bool exception_throws = !std::is_void<exception_type>::value && !detail::is_nothrow_swappable<exception_type>::value; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant #endif if(!exception_throws && !value_throws && !error_throws) { // Simples detail::basic_result_storage_swap<value_throws, error_throws>(*this, o); using std::swap; swap(this->_ptr, o._ptr); return; } struct _ { basic_outcome &a, &b; bool exceptioned{false}; bool all_good{false}; ~_() { if(!all_good) { // We lost one of the values a._state._status.set_have_lost_consistency(true); b._state._status.set_have_lost_consistency(true); return; } if(exceptioned) { // The value + error swap threw an exception. Try to swap back _ptr try { strong_swap(all_good, a._ptr, b._ptr); } catch(...) { // We lost one of the values a._state._status.set_have_lost_consistency(true); b._state._status.set_have_lost_consistency(true); // throw away second exception } // Prevent has_value() == has_error() or has_value() == has_exception() auto check = [](basic_outcome *t) { if(t->has_value() && (t->has_error() || t->has_exception())) { t->_state._status.set_have_error(false).set_have_exception(false); t->_state._status.set_have_lost_consistency(true); } if(!t->has_value() && !(t->has_error() || t->has_exception())) { // Choose error, for no particular reason t->_state._status.set_have_error(true).set_have_lost_consistency(true); } }; check(&a); check(&b); } } } _{*this, o}; strong_swap(_.all_good, this->_ptr, o._ptr); _.exceptioned = true; detail::basic_result_storage_swap<value_throws, error_throws>(*this, o); _.exceptioned = false; #ifdef _MSC_VER #pragma warning(pop) #endif #else detail::basic_result_storage_swap<false, false>(*this, o); using std::swap; swap(this->_ptr, o._ptr); #endif } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ failure_type<error_type, exception_type> as_failure() const & { if(this->has_error() && this->has_exception()) { return failure_type<error_type, exception_type>(this->assume_error(), this->assume_exception()); } if(this->has_exception()) { return failure_type<error_type, exception_type>(in_place_type<exception_type>, this->assume_exception()); } return failure_type<error_type, exception_type>(in_place_type<error_type>, this->assume_error()); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ failure_type<error_type, exception_type> as_failure() && { if(this->has_error() && this->has_exception()) { return failure_type<error_type, exception_type>(static_cast<S &&>(this->assume_error()), static_cast<P &&>(this->assume_exception())); } if(this->has_exception()) { return failure_type<error_type, exception_type>(in_place_type<exception_type>, static_cast<P &&>(this->assume_exception())); } return failure_type<error_type, exception_type>(in_place_type<error_type>, static_cast<S &&>(this->assume_error())); } #ifdef __APPLE__ failure_type<error_type, exception_type> _xcode_workaround_as_failure() &&; #endif }; // C++ 20 operator== rewriting should take care of this for us, indeed // if we don't disable it, we cause Concept recursion to infinity! #if __cplusplus < 202000L /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V, // class R, class S, class P, class N) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>())) constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( // noexcept(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>())) { return b == a; } #endif /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V, // class R, class S, class P, class N) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>())) constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( // noexcept(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>())) { return b != a; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class P, class N> inline void swap(basic_outcome<R, S, P, N> &a, basic_outcome<R, S, P, N> &b) noexcept(noexcept(a.swap(b))) { a.swap(b); } namespace hooks { /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class P, class NoValuePolicy, class U> constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept { o->_ptr = static_cast<U &&>(v); // NOLINT o->_state._status.set_have_exception(true); } } // namespace hooks BOOST_OUTCOME_V2_NAMESPACE_END #ifdef __clang__ #pragma clang diagnostic pop #endif #include "detail/basic_outcome_exception_observers_impl.hpp" #if !defined(NDEBUG) BOOST_OUTCOME_V2_NAMESPACE_BEGIN // Check is trivial in all ways except default constructibility and standard layout // static_assert(std::is_trivial<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivial!"); // static_assert(std::is_trivially_default_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially default // constructible!"); static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!"); static_assert(std::is_trivially_assignable<basic_outcome<int, long, double, policy::all_narrow>, basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially assignable!"); static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!"); static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy constructible!"); static_assert(std::is_trivially_move_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move constructible!"); static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!"); static_assert(std::is_trivially_move_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move assignable!"); // Can't be standard layout as non-static member data is defined in more than one inherited class // static_assert(std::is_standard_layout<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not a standard layout type!"); BOOST_OUTCOME_V2_NAMESPACE_END #endif #endif policy/base.hpp 0000644 00000010027 15125552774 0007503 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) and Andrzej Krzemieński <akrzemi1@gmail.com> (1 commit) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_BASE_HPP #define BOOST_OUTCOME_POLICY_BASE_HPP #include "../detail/value_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { namespace detail { using BOOST_OUTCOME_V2_NAMESPACE::detail::make_ub; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ struct base { protected: template <class Impl> static constexpr void _make_ub(Impl &&self) noexcept { return detail::make_ub(static_cast<Impl &&>(self)); } template <class Impl> static constexpr bool _has_value(Impl &&self) noexcept { return self._state._status.have_value(); } template <class Impl> static constexpr bool _has_error(Impl &&self) noexcept { return self._state._status.have_error(); } template <class Impl> static constexpr bool _has_exception(Impl &&self) noexcept { return self._state._status.have_exception(); } template <class Impl> static constexpr bool _has_error_is_errno(Impl &&self) noexcept { return self._state._status.have_error_is_errno(); } template <class Impl> static constexpr void _set_has_value(Impl &&self, bool v) noexcept { self._state._status.set_have_value(v); } template <class Impl> static constexpr void _set_has_error(Impl &&self, bool v) noexcept { self._state._status.set_have_error(v); } template <class Impl> static constexpr void _set_has_exception(Impl &&self, bool v) noexcept { self._state._status.set_have_exception(v); } template <class Impl> static constexpr void _set_has_error_is_errno(Impl &&self, bool v) noexcept { self._state._status.set_have_error_is_errno(v); } template <class Impl> static constexpr auto &&_value(Impl &&self) noexcept { return static_cast<Impl &&>(self)._state._value; } template <class Impl> static constexpr auto &&_error(Impl &&self) noexcept { return static_cast<Impl &&>(self)._error; } public: template <class R, class S, class P, class NoValuePolicy, class Impl> static inline constexpr auto &&_exception(Impl &&self) noexcept; template <class Impl> static constexpr void narrow_value_check(Impl &&self) noexcept { if(!_has_value(self)) { _make_ub(self); } } template <class Impl> static constexpr void narrow_error_check(Impl &&self) noexcept { if(!_has_error(self)) { _make_ub(self); } } template <class Impl> static constexpr void narrow_exception_check(Impl &&self) noexcept { if(!_has_exception(self)) { _make_ub(self); } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/fail_to_compile_observers.hpp 0000644 00000010536 15125552774 0014015 0 ustar 00 /* Policies for result and outcome (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (4 commits) File Created: Sep 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_FAIL_TO_COMPILE_OBSERVERS_HPP #define BOOST_OUTCOME_POLICY_FAIL_TO_COMPILE_OBSERVERS_HPP #include "base.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN #define BOOST_OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE \ "Attempt to wide observe value, error or " \ "exception for a basic_result/basic_outcome given an EC or EP type which is not void, and for whom " \ "trait::is_error_code_available<EC>, trait::is_exception_ptr_available<EC>, and trait::is_exception_ptr_available<EP> " \ "are all false. Please specify a NoValuePolicy to tell basic_result/basic_outcome what to do, or else use " \ "a more specific convenience type alias such as unchecked<T, E> to indicate you want the wide " \ "observers to be narrow, or checked<T, E> to indicate you always want an exception throw etc." namespace policy { struct fail_to_compile_observers : base { template <class Impl> static constexpr void wide_value_check(Impl && /* unused */) { static_assert(!std::is_same<Impl, Impl>::value, BOOST_OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE); } template <class Impl> static constexpr void wide_error_check(Impl && /* unused */) { static_assert(!std::is_same<Impl, Impl>::value, BOOST_OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE); } template <class Impl> static constexpr void wide_exception_check(Impl && /* unused */) { static_assert(!std::is_same<Impl, Impl>::value, BOOST_OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE); } }; } // namespace policy #undef BOOST_OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/outcome_exception_ptr_rethrow.hpp 0000644 00000006113 15125552774 0014762 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (10 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_OUTCOME_EXCEPTION_PTR_RETHROW_HPP #define BOOST_OUTCOME_POLICY_OUTCOME_EXCEPTION_PTR_RETHROW_HPP #include "result_exception_ptr_rethrow.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL type definition exception_ptr_rethrow. Potential doc page: NOT FOUND */ template <class T, class EC, class E> struct exception_ptr_rethrow : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(std::forward<Impl>(self))) { if(base::_has_exception(std::forward<Impl>(self))) { detail::_rethrow_exception<trait::is_exception_ptr_available<E>::value>{base::_exception<T, EC, E, exception_ptr_rethrow>(std::forward<Impl>(self))}; } if(base::_has_error(std::forward<Impl>(self))) { detail::_rethrow_exception<trait::is_exception_ptr_available<EC>::value>{base::_error(std::forward<Impl>(self))}; } BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no value")); // NOLINT } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { if(!base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no error")); // NOLINT } } template <class Impl> static constexpr void wide_exception_check(Impl &&self) { if(!base::_has_exception(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no exception")); // NOLINT } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/throw_bad_result_access.hpp 0000644 00000006563 15125552774 0013473 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (13 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_THROW_BAD_RESULT_ACCESS_HPP #define BOOST_OUTCOME_POLICY_THROW_BAD_RESULT_ACCESS_HPP #include "../bad_access.hpp" #include "base.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL type definition throw_bad_result_access. Potential doc page: NOT FOUND */ template <class EC, class EP> struct throw_bad_result_access : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no value")); // NOLINT } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { if(!base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no error")); // NOLINT } } template <class Impl> static constexpr void wide_exception_check(Impl &&self) { if(!base::_has_exception(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no exception")); // NOLINT } } }; template <class EC> struct throw_bad_result_access<EC, void> : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(std::forward<Impl>(self))) { if(base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access_with<EC>(base::_error(std::forward<Impl>(self)))); } BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access("no value")); // NOLINT } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { if(!base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access("no error")); // NOLINT } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/all_narrow.hpp 0000644 00000004334 15125552774 0010735 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (13 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_ALL_NARROW_HPP #define BOOST_OUTCOME_POLICY_ALL_NARROW_HPP #include "base.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL type definition all_narrow. Potential doc page: `all_narrow` */ struct all_narrow : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { base::narrow_value_check(static_cast<Impl &&>(self)); } template <class Impl> static constexpr void wide_error_check(Impl &&self) { base::narrow_error_check(static_cast<Impl &&>(self)); } template <class Impl> static constexpr void wide_exception_check(Impl &&self) { base::narrow_exception_check(static_cast<Impl &&>(self)); } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/result_error_code_throw_as_system_error.hpp 0000644 00000005276 15125552774 0017047 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (8 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_RESULT_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP #define BOOST_OUTCOME_POLICY_RESULT_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP #include "../bad_access.hpp" #include "base.hpp" #include <system_error> BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { template <class T, class EC, class E> struct error_code_throw_as_system_error; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class EC> struct error_code_throw_as_system_error<T, EC, void> : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(std::forward<Impl>(self))) { if(base::_has_error(std::forward<Impl>(self))) { // ADL discovered outcome_throw_as_system_error_with_payload(base::_error(std::forward<Impl>(self))); } BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access("no value")); // NOLINT } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { if(!base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access("no error")); // NOLINT } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/outcome_error_code_throw_as_system_error.hpp 0000644 00000006226 15125552774 0017200 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_OUTCOME_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP #define BOOST_OUTCOME_POLICY_OUTCOME_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP #include "result_error_code_throw_as_system_error.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL type definition error_code_throw_as_system_error. Potential doc page: NOT FOUND */ template <class T, class EC, class E> struct error_code_throw_as_system_error : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(std::forward<Impl>(self))) { if(base::_has_exception(std::forward<Impl>(self))) { detail::_rethrow_exception<trait::is_exception_ptr_available<E>::value>{base::_exception<T, EC, E, error_code_throw_as_system_error>(std::forward<Impl>(self))}; // NOLINT } if(base::_has_error(std::forward<Impl>(self))) { // ADL discovered outcome_throw_as_system_error_with_payload(base::_error(std::forward<Impl>(self))); } BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no value")); // NOLINT } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { if(!base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no error")); // NOLINT } } template <class Impl> static constexpr void wide_exception_check(Impl &&self) { if(!base::_has_exception(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_outcome_access("no exception")); // NOLINT } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/terminate.hpp 0000644 00000004604 15125552774 0010565 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_TERMINATE_HPP #define BOOST_OUTCOME_POLICY_TERMINATE_HPP #include "base.hpp" #include <cstdlib> BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL type definition terminate. Potential doc page: `terminate` */ struct terminate : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(static_cast<Impl &&>(self))) { std::abort(); } } template <class Impl> static constexpr void wide_error_check(Impl &&self) noexcept { if(!base::_has_error(static_cast<Impl &&>(self))) { std::abort(); } } template <class Impl> static constexpr void wide_exception_check(Impl &&self) { if(!base::_has_exception(static_cast<Impl &&>(self))) { std::abort(); } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif policy/result_exception_ptr_rethrow.hpp 0000644 00000005154 15125552774 0014631 0 ustar 00 /* Policies for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_POLICY_RESULT_EXCEPTION_PTR_RETHROW_HPP #define BOOST_OUTCOME_POLICY_RESULT_EXCEPTION_PTR_RETHROW_HPP #include "../bad_access.hpp" #include "base.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class EC, class E> struct exception_ptr_rethrow; template <class T, class EC> struct exception_ptr_rethrow<T, EC, void> : base { template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(std::forward<Impl>(self))) { if(base::_has_error(std::forward<Impl>(self))) { // ADL rethrow_exception(policy::exception_ptr(base::_error(std::forward<Impl>(self)))); } BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access("no value")); // NOLINT } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { if(!base::_has_error(std::forward<Impl>(self))) { BOOST_OUTCOME_THROW_EXCEPTION(bad_result_access("no error")); // NOLINT } } }; } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #endif experimental/result.h 0000644 00000014067 15125552774 0010755 0 ustar 00 /* C interface for result (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) File Created: Aug 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_EXPERIMENTAL_RESULT_H #define BOOST_OUTCOME_EXPERIMENTAL_RESULT_H #include <stdint.h> // for intptr_t #define BOOST_OUTCOME_C_DECLARE_RESULT(ident, R, S) \ struct cxx_result_##ident \ { \ R value; \ unsigned flags; \ S error; \ } #define BOOST_OUTCOME_C_RESULT(ident) struct cxx_result_##ident #define BOOST_OUTCOME_C_RESULT_HAS_VALUE(r) (((r).flags & 1U) == 1U) #define BOOST_OUTCOME_C_RESULT_HAS_ERROR(r) (((r).flags & 2U) == 2U) #define BOOST_OUTCOME_C_RESULT_ERROR_IS_ERRNO(r) (((r).flags & (1U << 4U)) == (1U << 4U)) /***************************** <system_error2> support ******************************/ #define BOOST_OUTCOME_C_DECLARE_STATUS_CODE(ident, value_type) \ struct cxx_status_code_##ident \ { \ void *domain; \ value_type value; \ }; #define BOOST_OUTCOME_C_STATUS_CODE(ident) struct cxx_status_code_##ident struct cxx_status_code_posix { void *domain; int value; }; #define BOOST_OUTCOME_C_DECLARE_RESULT_ERRNO(ident, R) BOOST_OUTCOME_C_DECLARE_RESULT(posix_##ident, R, struct cxx_status_code_posix) #define BOOST_OUTCOME_C_RESULT_ERRNO(ident) BOOST_OUTCOME_C_RESULT(posix_##ident) struct cxx_status_code_system { void *domain; intptr_t value; }; #define BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(ident, R) BOOST_OUTCOME_C_DECLARE_RESULT(system_##ident, R, struct cxx_status_code_system) #define BOOST_OUTCOME_C_RESULT_SYSTEM(ident) BOOST_OUTCOME_C_RESULT(system_##ident) #endif experimental/status_outcome.hpp 0000644 00000012331 15125552774 0013045 0 ustar 00 /* A less simple result type (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (17 commits) File Created: Apr 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_EXPERIMENTAL_STATUS_OUTCOME_HPP #define BOOST_OUTCOME_EXPERIMENTAL_STATUS_OUTCOME_HPP #include "../basic_outcome.hpp" #include "../detail/trait_std_exception.hpp" #include "status_result.hpp" #include "boost/exception_ptr.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN template <class DomainType> inline std::exception_ptr basic_outcome_failure_exception_from_error(const status_code<DomainType> &sc) { (void) sc; #ifndef BOOST_NO_EXCEPTIONS try { sc.throw_exception(); } catch(...) { return std::current_exception(); } #endif return {}; } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace experimental { namespace policy { template <class T, class EC, class E> using default_status_outcome_policy = std::conditional_t< // std::is_void<EC>::value && std::is_void<E>::value, // BOOST_OUTCOME_V2_NAMESPACE::policy::terminate, // std::conditional_t<(is_status_code<EC>::value || is_errored_status_code<EC>::value) && (std::is_void<E>::value || BOOST_OUTCOME_V2_NAMESPACE::trait::is_exception_ptr_available<E>::value), // status_code_throw<T, EC, E>, // BOOST_OUTCOME_V2_NAMESPACE::policy::fail_to_compile_observers // >>; } // namespace policy /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S = system_code, class P = std::exception_ptr, class NoValuePolicy = policy::default_status_outcome_policy<R, S, P>> // using status_outcome = basic_outcome<R, S, P, NoValuePolicy>; namespace policy { template <class T, class DomainType, class E> struct status_code_throw<T, status_code<DomainType>, E> : base { using _base = base; template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(static_cast<Impl &&>(self))) { if(base::_has_exception(static_cast<Impl &&>(self))) { BOOST_OUTCOME_V2_NAMESPACE::policy::detail::_rethrow_exception<trait::is_exception_ptr_available<E>::value>(base::_exception<T, status_code<DomainType>, E, status_code_throw>(static_cast<Impl &&>(self))); // NOLINT } if(base::_has_error(static_cast<Impl &&>(self))) { #ifndef BOOST_NO_EXCEPTIONS base::_error(static_cast<Impl &&>(self)).throw_exception(); #else BOOST_OUTCOME_THROW_EXCEPTION("wide value check failed"); #endif } } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { _base::narrow_error_check(static_cast<Impl &&>(self)); } template <class Impl> static constexpr void wide_exception_check(Impl &&self) { _base::narrow_exception_check(static_cast<Impl &&>(self)); } }; template <class T, class DomainType, class E> struct status_code_throw<T, errored_status_code<DomainType>, E> : status_code_throw<T, status_code<DomainType>, E> { status_code_throw() = default; using status_code_throw<T, status_code<DomainType>, E>::status_code_throw; }; } // namespace policy } // namespace experimental BOOST_OUTCOME_V2_NAMESPACE_END #endif experimental/status_result.hpp 0000644 00000014367 15125552774 0012723 0 ustar 00 /* A very simple result type (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (11 commits) File Created: Apr 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_EXPERIMENTAL_STATUS_RESULT_HPP #define BOOST_OUTCOME_EXPERIMENTAL_STATUS_RESULT_HPP #include "../basic_result.hpp" #include "../policy/fail_to_compile_observers.hpp" #include "status-code/system_error2.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace trait { namespace detail { // Shortcut this for lower build impact. Used to tell outcome's converting constructors // that they can do E => EC or E => EP as necessary. template <class DomainType> struct _is_error_code_available<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<DomainType>> { static constexpr bool value = true; using type = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<DomainType>; }; template <class DomainType> struct _is_error_code_available<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errored_status_code<DomainType>> { static constexpr bool value = true; using type = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errored_status_code<DomainType>; }; } // namespace detail #if 0 // Do NOT enable weakened implicit construction for these types template <class DomainType> struct is_error_type<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<DomainType>> { static constexpr bool value = true; }; template <> struct is_error_type<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc> { static constexpr bool value = true; }; template <class DomainType, class Enum> struct is_error_type_enum<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<DomainType>, Enum> { static constexpr bool value = boost::system::is_error_condition_enum<Enum>::value; }; #endif } // namespace trait namespace detail { // Customise _set_error_is_errno template <class State> constexpr inline void _set_error_is_errno(State &state, const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::generic_code & /*unused*/) { state._status.set_have_error_is_errno(true); } #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX template <class State> constexpr inline void _set_error_is_errno(State &state, const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::posix_code & /*unused*/) { state._status.set_have_error_is_errno(true); } #endif template <class State> constexpr inline void _set_error_is_errno(State &state, const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc & /*unused*/) { state._status.set_have_error_is_errno(true); } } // namespace detail namespace experimental { using namespace BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE; using BOOST_OUTCOME_V2_NAMESPACE::failure; using BOOST_OUTCOME_V2_NAMESPACE::success; namespace policy { using namespace BOOST_OUTCOME_V2_NAMESPACE::policy; template <class T, class EC, class E> struct status_code_throw { static_assert(!std::is_same<T, T>::value, "policy::status_code_throw not specialised for these types, did you use status_result<T, status_code<DomainType>, E>?"); }; template <class T, class DomainType> struct status_code_throw<T, status_code<DomainType>, void> : base { using _base = base; template <class Impl> static constexpr void wide_value_check(Impl &&self) { if(!base::_has_value(static_cast<Impl &&>(self))) { if(base::_has_error(static_cast<Impl &&>(self))) { #ifndef BOOST_NO_EXCEPTIONS base::_error(static_cast<Impl &&>(self)).throw_exception(); #else BOOST_OUTCOME_THROW_EXCEPTION("wide value check failed"); #endif } } } template <class Impl> static constexpr void wide_error_check(Impl &&self) { _base::narrow_error_check(static_cast<Impl &&>(self)); } }; template <class T, class DomainType> struct status_code_throw<T, errored_status_code<DomainType>, void> : status_code_throw<T, status_code<DomainType>, void> { status_code_throw() = default; using status_code_throw<T, status_code<DomainType>, void>::status_code_throw; }; template <class T, class EC> using default_status_result_policy = std::conditional_t< // std::is_void<EC>::value, // BOOST_OUTCOME_V2_NAMESPACE::policy::terminate, // std::conditional_t<is_status_code<EC>::value || is_errored_status_code<EC>::value, // status_code_throw<T, EC, void>, // BOOST_OUTCOME_V2_NAMESPACE::policy::fail_to_compile_observers // >>; } // namespace policy /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S = system_code, class NoValuePolicy = policy::default_status_result_policy<R, S>> // using status_result = basic_result<R, S, NoValuePolicy>; } // namespace experimental BOOST_OUTCOME_V2_NAMESPACE_END #endif experimental/coroutine_support.hpp 0000644 00000014363 15125552774 0013601 0 ustar 00 /* Tells C++ coroutines about Outcome's result (C) 2019-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) File Created: Oct 2019 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_EXPERIMENTAL_COROUTINE_SUPPORT_HPP #define BOOST_OUTCOME_EXPERIMENTAL_COROUTINE_SUPPORT_HPP #include "../config.hpp" #define BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN \ BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace experimental \ { \ namespace awaitables \ { // #define BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN \ BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace experimental \ { \ namespace awaitables \ { // #define BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END \ } \ } \ BOOST_OUTCOME_V2_NAMESPACE_END #ifndef BOOST_NO_EXCEPTIONS #include "status-code/system_code_from_exception.hpp" BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace awaitables { namespace detail { inline bool error_is_set(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code &sc) noexcept { return sc.failure(); } inline BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code error_from_exception(std::exception_ptr &&ep = std::current_exception(), BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code not_matched = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::generic_code(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc::resource_unavailable_try_again)) noexcept { return BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code_from_exception(static_cast<std::exception_ptr &&>(ep), static_cast<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code &&>(not_matched)); } } // namespace detail } // namespace awaitables BOOST_OUTCOME_V2_NAMESPACE_END #endif #include "../detail/coroutine_support.ipp" #undef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN #undef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN #undef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END #endif experimental/status-code/quick_status_code_from_enum.hpp 0000644 00000017204 15125552774 0020006 0 ustar 00 /* Proposed SG14 status_code (C) 2018 - 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: May 2020 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License in the accompanying file Licence.txt or at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Distributed under the Boost Software License, Version 1.0. (See accompanying file Licence.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_HPP #include "generic_code.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN template <class Enum> class _quick_status_code_from_enum_domain; //! A status code wrapping `Enum` generated from `quick_status_code_from_enum`. template <class Enum> using quick_status_code_from_enum_code = status_code<_quick_status_code_from_enum_domain<Enum>>; //! Defaults for an implementation of `quick_status_code_from_enum<Enum>` template <class Enum> struct quick_status_code_from_enum_defaults { //! The type of the resulting code using code_type = quick_status_code_from_enum_code<Enum>; //! Used within `quick_status_code_from_enum` to define a mapping of enumeration value with its status code struct mapping { //! The enumeration type using enumeration_type = Enum; //! The value being mapped const Enum value; //! A string representation for this enumeration value const char *message; //! A list of `errc` equivalents for this enumeration value const std::initializer_list<errc> code_mappings; }; //! Used within `quick_status_code_from_enum` to define mixins for the status code wrapping `Enum` template <class Base> struct mixin : Base { using Base::Base; }; }; /*! The implementation of the domain for status codes wrapping `Enum` generated from `quick_status_code_from_enum`. */ template <class Enum> class _quick_status_code_from_enum_domain : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; using _base = status_code_domain; using _src = quick_status_code_from_enum<Enum>; public: //! The value type of the quick status code from enum using value_type = Enum; using _base::string_ref; constexpr _quick_status_code_from_enum_domain() : status_code_domain(_src::domain_uuid, _uuid_size<detail::cstrlen(_src::domain_uuid)>()) { } _quick_status_code_from_enum_domain(const _quick_status_code_from_enum_domain &) = default; _quick_status_code_from_enum_domain(_quick_status_code_from_enum_domain &&) = default; _quick_status_code_from_enum_domain &operator=(const _quick_status_code_from_enum_domain &) = default; _quick_status_code_from_enum_domain &operator=(_quick_status_code_from_enum_domain &&) = default; ~_quick_status_code_from_enum_domain() = default; #if __cplusplus < 201402L && !defined(_MSC_VER) static inline const _quick_status_code_from_enum_domain &get() { static _quick_status_code_from_enum_domain v; return v; } #else static inline constexpr const _quick_status_code_from_enum_domain &get(); #endif virtual string_ref name() const noexcept override { return string_ref(_src::domain_name); } protected: // Not sure if a hash table is worth it here, most enumerations won't be long enough to be worth it // Also, until C++ 20's consteval, the hash table would get emitted into the binary, bloating it static BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 const typename _src::mapping *_find_mapping(value_type v) noexcept { for(const auto &i : _src::value_mappings()) { if(i.value == v) { return &i; } } return nullptr; } virtual bool _do_failure(const status_code<void> &code) const noexcept override { assert(code.domain() == *this); // NOLINT // If `errc::success` is in the generic code mapping, it is not a failure const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value()); assert(mapping != nullptr); if(mapping != nullptr) { for(errc ec : mapping->code_mappings) { if(ec == errc::success) { return false; } } } return true; } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override { assert(code1.domain() == *this); // NOLINT const auto &c1 = static_cast<const quick_status_code_from_enum_code<value_type> &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const quick_status_code_from_enum_code<value_type> &>(code2); // NOLINT return c1.value() == c2.value(); } if(code2.domain() == generic_code_domain) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT const auto *mapping = _find_mapping(c1.value()); assert(mapping != nullptr); if(mapping != nullptr) { for(errc ec : mapping->code_mappings) { if(ec == c2.value()) { return true; } } } } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override { assert(code.domain() == *this); // NOLINT const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value()); assert(mapping != nullptr); if(mapping != nullptr) { if(mapping->code_mappings.size() > 0) { return *mapping->code_mappings.begin(); } } return errc::unknown; } virtual string_ref _do_message(const status_code<void> &code) const noexcept override { assert(code.domain() == *this); // NOLINT const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value()); assert(mapping != nullptr); if(mapping != nullptr) { return string_ref(mapping->message); } return string_ref("unknown"); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const quick_status_code_from_enum_code<value_type> &>(code); // NOLINT throw status_error<_quick_status_code_from_enum_domain>(c); } #endif }; #if __cplusplus >= 201402L || defined(_MSC_VER) template <class Enum> constexpr _quick_status_code_from_enum_domain<Enum> quick_status_code_from_enum_domain = {}; template <class Enum> inline constexpr const _quick_status_code_from_enum_domain<Enum> &_quick_status_code_from_enum_domain<Enum>::get() { return quick_status_code_from_enum_domain<Enum>; } #endif namespace mixins { template <class Base, class Enum> struct mixin<Base, _quick_status_code_from_enum_domain<Enum>> : public quick_status_code_from_enum<Enum>::template mixin<Base> { using quick_status_code_from_enum<Enum>::template mixin<Base>::mixin; }; } // namespace mixins BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/errored_status_code.hpp 0000644 00000051511 15125552774 0016264 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Jun 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_ERRORED_STATUS_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_ERRORED_STATUS_CODE_HPP #include "quick_status_code_from_enum.hpp" #include "status_code_ptr.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! A `status_code` which is always a failure. The closest equivalent to `std::error_code`, except it cannot be modified, and is templated. Differences from `status_code`: - Never successful (this contract is checked on construction, if fails then it terminates the process). - Is immutable. */ template <class DomainType> class errored_status_code : public status_code<DomainType> { using _base = status_code<DomainType>; using _base::clear; using _base::success; void _check() { if(_base::success()) { std::terminate(); } } public: //! The type of the erased error code. using typename _base::value_type; //! The type of a reference to a message string. using typename _base::string_ref; //! Default constructor. errored_status_code() = default; //! Copy constructor. errored_status_code(const errored_status_code &) = default; //! Move constructor. errored_status_code(errored_status_code &&) = default; // NOLINT //! Copy assignment. errored_status_code &operator=(const errored_status_code &) = default; //! Move assignment. errored_status_code &operator=(errored_status_code &&) = default; // NOLINT ~errored_status_code() = default; //! Explicitly construct from any similarly erased status code explicit errored_status_code(const _base &o) noexcept(std::is_nothrow_copy_constructible<_base>::value) : _base(o) { _check(); } //! Explicitly construct from any similarly erased status code explicit errored_status_code(_base &&o) noexcept(std::is_nothrow_move_constructible<_base>::value) : _base(static_cast<_base &&>(o)) { _check(); } /***** KEEP THESE IN SYNC WITH STATUS_CODE *****/ //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`. template <class T, class... Args, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<T, Args...>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<!std::is_same<typename std::decay<T>::type, errored_status_code>::value // not copy/move of self && !std::is_same<typename std::decay<T>::type, in_place_t>::value // not in_place_t && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code && std::is_constructible<errored_status_code, MakeStatusCodeResult>::value, // ADLed status code is compatible bool>::type = true> errored_status_code(T &&v, Args &&... args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT : errored_status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...)) { _check(); } //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type. template <class Enum, // class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type, // Enumeration has been activated typename std::enable_if<std::is_constructible<errored_status_code, QuickStatusCodeType>::value, // Its status code is compatible bool>::type = true> errored_status_code(Enum &&v) noexcept(std::is_nothrow_constructible<errored_status_code, QuickStatusCodeType>::value) // NOLINT : errored_status_code(QuickStatusCodeType(static_cast<Enum &&>(v))) { _check(); } //! Explicit in-place construction. template <class... Args> explicit errored_status_code(in_place_t _, Args &&... args) noexcept(std::is_nothrow_constructible<value_type, Args &&...>::value) : _base(_, static_cast<Args &&>(args)...) { _check(); } //! Explicit in-place construction from initialiser list. template <class T, class... Args> explicit errored_status_code(in_place_t _, std::initializer_list<T> il, Args &&... args) noexcept(std::is_nothrow_constructible<value_type, std::initializer_list<T>, Args &&...>::value) : _base(_, il, static_cast<Args &&>(args)...) { _check(); } //! Explicit copy construction from a `value_type`. explicit errored_status_code(const value_type &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value) : _base(v) { _check(); } //! Explicit move construction from a `value_type`. explicit errored_status_code(value_type &&v) noexcept(std::is_nothrow_move_constructible<value_type>::value) : _base(static_cast<value_type &&>(v)) { _check(); } /*! Explicit construction from an erased status code. Available only if `value_type` is trivially destructible and `sizeof(status_code) <= sizeof(status_code<erased<>>)`. Does not check if domains are equal. */ template <class ErasedType, // typename std::enable_if<detail::type_erasure_is_safe<ErasedType, value_type>::value, bool>::type = true> explicit errored_status_code(const status_code<erased<ErasedType>> &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value) : errored_status_code(detail::erasure_cast<value_type>(v.value())) // NOLINT { assert(v.domain() == this->domain()); // NOLINT _check(); } //! Always false (including at compile time), as errored status codes are never successful. constexpr bool success() const noexcept { return false; } //! Return a const reference to the `value_type`. constexpr const value_type &value() const &noexcept { return this->_value; } }; namespace traits { template <class DomainType> struct is_move_bitcopying<errored_status_code<DomainType>> { static constexpr bool value = is_move_bitcopying<typename DomainType::value_type>::value; }; } // namespace traits template <class ErasedType> class errored_status_code<erased<ErasedType>> : public status_code<erased<ErasedType>> { using _base = status_code<erased<ErasedType>>; using _base::success; void _check() { if(_base::success()) { std::terminate(); } } public: using value_type = typename _base::value_type; using string_ref = typename _base::string_ref; //! Default construction to empty errored_status_code() = default; //! Copy constructor errored_status_code(const errored_status_code &) = default; //! Move constructor errored_status_code(errored_status_code &&) = default; // NOLINT //! Copy assignment errored_status_code &operator=(const errored_status_code &) = default; //! Move assignment errored_status_code &operator=(errored_status_code &&) = default; // NOLINT ~errored_status_code() = default; //! Explicitly construct from any similarly erased status code explicit errored_status_code(const _base &o) noexcept(std::is_nothrow_copy_constructible<_base>::value) : _base(o) { _check(); } //! Explicitly construct from any similarly erased status code explicit errored_status_code(_base &&o) noexcept(std::is_nothrow_move_constructible<_base>::value) : _base(static_cast<_base &&>(o)) { _check(); } /***** KEEP THESE IN SYNC WITH STATUS_CODE *****/ //! Implicit copy construction from any other status code if its value type is trivially copyable and it would fit into our storage template <class DomainType, // typename std::enable_if<std::is_trivially_copyable<typename DomainType::value_type>::value // && detail::type_erasure_is_safe<value_type, typename DomainType::value_type>::value, bool>::type = true> errored_status_code(const status_code<DomainType> &v) noexcept : _base(v) // NOLINT { _check(); } //! Implicit copy construction from any other status code if its value type is trivially copyable and it would fit into our storage template <class DomainType, // typename std::enable_if<std::is_trivially_copyable<typename DomainType::value_type>::value // && detail::type_erasure_is_safe<value_type, typename DomainType::value_type>::value, bool>::type = true> errored_status_code(const errored_status_code<DomainType> &v) noexcept : _base(static_cast<const status_code<DomainType> &>(v)) // NOLINT { _check(); } //! Implicit move construction from any other status code if its value type is trivially copyable or move bitcopying and it would fit into our storage template <class DomainType, // typename std::enable_if<detail::type_erasure_is_safe<value_type, typename DomainType::value_type>::value, bool>::type = true> errored_status_code(status_code<DomainType> &&v) noexcept : _base(static_cast<status_code<DomainType> &&>(v)) // NOLINT { _check(); } //! Implicit move construction from any other status code if its value type is trivially copyable or move bitcopying and it would fit into our storage template <class DomainType, // typename std::enable_if<detail::type_erasure_is_safe<value_type, typename DomainType::value_type>::value, bool>::type = true> errored_status_code(errored_status_code<DomainType> &&v) noexcept : _base(static_cast<status_code<DomainType> &&>(v)) // NOLINT { _check(); } //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`. template <class T, class... Args, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<T, Args...>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<!std::is_same<typename std::decay<T>::type, errored_status_code>::value // not copy/move of self && !std::is_same<typename std::decay<T>::type, value_type>::value // not copy/move of value type && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code && std::is_constructible<errored_status_code, MakeStatusCodeResult>::value, // ADLed status code is compatible bool>::type = true> errored_status_code(T &&v, Args &&... args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT : errored_status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...)) { _check(); } //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type. template <class Enum, // class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type, // Enumeration has been activated typename std::enable_if<std::is_constructible<errored_status_code, QuickStatusCodeType>::value, // Its status code is compatible bool>::type = true> errored_status_code(Enum &&v) noexcept(std::is_nothrow_constructible<errored_status_code, QuickStatusCodeType>::value) // NOLINT : errored_status_code(QuickStatusCodeType(static_cast<Enum &&>(v))) { _check(); } //! Always false (including at compile time), as errored status codes are never successful. constexpr bool success() const noexcept { return false; } //! Return the erased `value_type` by value. constexpr value_type value() const noexcept { return this->_value; } }; namespace traits { template <class ErasedType> struct is_move_bitcopying<errored_status_code<erased<ErasedType>>> { static constexpr bool value = true; }; } // namespace traits //! True if the status code's are semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator==(const errored_status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept { return a.equivalent(static_cast<const status_code<DomainType2> &>(b)); } //! True if the status code's are semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator==(const status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept { return a.equivalent(static_cast<const status_code<DomainType2> &>(b)); } //! True if the status code's are semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator==(const errored_status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept { return static_cast<const status_code<DomainType1> &>(a).equivalent(b); } //! True if the status code's are not semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator!=(const errored_status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept { return !a.equivalent(static_cast<const status_code<DomainType2> &>(b)); } //! True if the status code's are not semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator!=(const status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept { return !a.equivalent(static_cast<const status_code<DomainType2> &>(b)); } //! True if the status code's are not semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator!=(const errored_status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept { return !static_cast<const status_code<DomainType1> &>(a).equivalent(b); } //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. template <class DomainType1, class T, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator==(const errored_status_code<DomainType1> &a, const T &b) { return a.equivalent(make_status_code(b)); } //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. template <class T, class DomainType1, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator==(const T &a, const errored_status_code<DomainType1> &b) { return b.equivalent(make_status_code(a)); } //! True if the status code's are not semantically equal via `equivalent()` to `make_status_code(T)`. template <class DomainType1, class T, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator!=(const errored_status_code<DomainType1> &a, const T &b) { return !a.equivalent(make_status_code(b)); } //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. template <class T, class DomainType1, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator!=(const T &a, const errored_status_code<DomainType1> &b) { return !b.equivalent(make_status_code(a)); } //! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`. template <class DomainType1, class T, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator==(const errored_status_code<DomainType1> &a, const T &b) { return a.equivalent(QuickStatusCodeType(b)); } //! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`. template <class T, class DomainType1, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator==(const T &a, const errored_status_code<DomainType1> &b) { return b.equivalent(QuickStatusCodeType(a)); } //! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`. template <class DomainType1, class T, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator!=(const errored_status_code<DomainType1> &a, const T &b) { return !a.equivalent(QuickStatusCodeType(b)); } //! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`. template <class T, class DomainType1, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator!=(const T &a, const errored_status_code<DomainType1> &b) { return !b.equivalent(QuickStatusCodeType(a)); } namespace detail { template <class T> struct is_errored_status_code { static constexpr bool value = false; }; template <class T> struct is_errored_status_code<errored_status_code<T>> { static constexpr bool value = true; }; template <class T> struct is_erased_errored_status_code { static constexpr bool value = false; }; template <class T> struct is_erased_errored_status_code<errored_status_code<erased<T>>> { static constexpr bool value = true; }; } // namespace detail //! Trait returning true if the type is an errored status code. template <class T> struct is_errored_status_code { static constexpr bool value = detail::is_errored_status_code<typename std::decay<T>::type>::value || detail::is_erased_errored_status_code<typename std::decay<T>::type>::value; }; BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/status_code_ptr.hpp 0000644 00000017001 15125552774 0015423 0 ustar 00 /* Pointer to a SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Sep 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_CODE_PTR_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_CODE_PTR_HPP #include "status_code.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN namespace detail { template <class StatusCode> class indirecting_domain : public status_code_domain { template <class DomainType> friend class status_code; using _base = status_code_domain; public: using value_type = StatusCode *; using _base::string_ref; constexpr indirecting_domain() noexcept : _base(0xc44f7bdeb2cc50e9 ^ typename StatusCode::domain_type().id() /* unique-ish based on domain's unique id */) { } indirecting_domain(const indirecting_domain &) = default; indirecting_domain(indirecting_domain &&) = default; // NOLINT indirecting_domain &operator=(const indirecting_domain &) = default; indirecting_domain &operator=(indirecting_domain &&) = default; // NOLINT ~indirecting_domain() = default; #if __cplusplus < 201402L && !defined(_MSC_VER) static inline const indirecting_domain &get() { static indirecting_domain v; return v; } #else static inline constexpr const indirecting_domain &get(); #endif virtual string_ref name() const noexcept override { return typename StatusCode::domain_type().name(); } // NOLINT protected: using _mycode = status_code<indirecting_domain>; virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const _mycode &>(code); // NOLINT return typename StatusCode::domain_type()._do_failure(*c.value()); } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); const auto &c1 = static_cast<const _mycode &>(code1); // NOLINT return typename StatusCode::domain_type()._do_equivalent(*c1.value(), code2); } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const _mycode &>(code); // NOLINT return typename StatusCode::domain_type()._generic_code(*c.value()); } virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const _mycode &>(code); // NOLINT return typename StatusCode::domain_type()._do_message(*c.value()); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const _mycode &>(code); // NOLINT typename StatusCode::domain_type()._do_throw_exception(*c.value()); } #endif virtual void _do_erased_copy(status_code<void> &dst, const status_code<void> &src, size_t /*unused*/) const override // NOLINT { // Note that dst will not have its domain set assert(src.domain() == *this); auto &d = static_cast<_mycode &>(dst); // NOLINT const auto &_s = static_cast<const _mycode &>(src); // NOLINT const StatusCode &s = *_s.value(); new(&d) _mycode(in_place, new StatusCode(s)); } virtual void _do_erased_destroy(status_code<void> &code, size_t /*unused*/) const noexcept override // NOLINT { assert(code.domain() == *this); auto &c = static_cast<_mycode &>(code); // NOLINT delete c.value(); // NOLINT } }; #if __cplusplus >= 201402L || defined(_MSC_VER) template <class StatusCode> constexpr indirecting_domain<StatusCode> _indirecting_domain{}; template <class StatusCode> inline constexpr const indirecting_domain<StatusCode> &indirecting_domain<StatusCode>::get() { return _indirecting_domain<StatusCode>; } #endif } // namespace detail /*! Make an erased status code which indirects to a dynamically allocated status code. This is useful for shoehorning a rich status code with large value type into a small erased status code like `system_code`, with which the status code generated by this function is compatible. Note that this function can throw due to `bad_alloc`. */ template <class T, typename std::enable_if<is_status_code<T>::value, bool>::type = true> // inline status_code<erased<typename std::add_pointer<typename std::decay<T>::type>::type>> make_status_code_ptr(T &&v) { using status_code_type = typename std::decay<T>::type; return status_code<detail::indirecting_domain<status_code_type>>(in_place, new status_code_type(static_cast<T &&>(v))); } /*! If a status code refers to a `status_code_ptr` which indirects to a status code of type `StatusCode`, return a pointer to that `StatusCode`. Otherwise return null. */ template <class StatusCode, class U, typename std::enable_if<is_status_code<StatusCode>::value, bool>::type = true> inline StatusCode *get_if(status_code<erased<U>> *v) noexcept { if((0xc44f7bdeb2cc50e9 ^ typename StatusCode::domain_type().id()) != v->domain().id()) { return nullptr; } union { U value; StatusCode *ret; }; value = v->value(); return ret; } //! \overload Const overload template <class StatusCode, class U, typename std::enable_if<is_status_code<StatusCode>::value, bool>::type = true> inline const StatusCode *get_if(const status_code<erased<U>> *v) noexcept { if((0xc44f7bdeb2cc50e9 ^ typename StatusCode::domain_type().id()) != v->domain().id()) { return nullptr; } union { U value; const StatusCode *ret; }; value = v->value(); return ret; } /*! If a status code refers to a `status_code_ptr`, return the id of the erased status code's domain. Otherwise return a meaningless number. */ template <class U> inline typename status_code_domain::unique_id_type get_id(const status_code<erased<U>> &v) noexcept { return 0xc44f7bdeb2cc50e9 ^ v.domain().id(); } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/win32_code.hpp 0000644 00000021364 15125552774 0014164 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_WIN32_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_WIN32_CODE_HPP #if !defined(_WIN32) && !defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) #error This file should only be included on Windows #endif #include "quick_status_code_from_enum.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN //! \exclude namespace win32 { // A Win32 DWORD using DWORD = unsigned long; // Used to retrieve the current Win32 error code extern DWORD __stdcall GetLastError(); // Used to retrieve a locale-specific message string for some error code extern DWORD __stdcall FormatMessageW(DWORD dwFlags, const void *lpSource, DWORD dwMessageId, DWORD dwLanguageId, wchar_t *lpBuffer, DWORD nSize, void /*va_list*/ *Arguments); // Converts UTF-16 message string to UTF-8 extern int __stdcall WideCharToMultiByte(unsigned int CodePage, DWORD dwFlags, const wchar_t *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, const char *lpDefaultChar, int *lpUsedDefaultChar); #pragma comment(lib, "kernel32.lib") #if defined(_WIN64) #pragma comment(linker, "/alternatename:?GetLastError@win32@system_error2@@YAKXZ=GetLastError") #pragma comment(linker, "/alternatename:?FormatMessageW@win32@system_error2@@YAKKPEBXKKPEA_WKPEAX@Z=FormatMessageW") #pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@system_error2@@YAHIKPEB_WHPEADHPEBDPEAH@Z=WideCharToMultiByte") #else #pragma comment(linker, "/alternatename:?GetLastError@win32@system_error2@@YGKXZ=__imp__GetLastError@0") #pragma comment(linker, "/alternatename:?FormatMessageW@win32@system_error2@@YGKKPBXKKPA_WKPAX@Z=__imp__FormatMessageW@28") #pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@system_error2@@YGHIKPB_WHPADHPBDPAH@Z=__imp__WideCharToMultiByte@32") #endif } // namespace win32 class _win32_code_domain; class _com_code_domain; //! (Windows only) A Win32 error code, those returned by `GetLastError()`. using win32_code = status_code<_win32_code_domain>; //! (Windows only) A specialisation of `status_error` for the Win32 error code domain. using win32_error = status_error<_win32_code_domain>; namespace mixins { template <class Base> struct mixin<Base, _win32_code_domain> : public Base { using Base::Base; //! Returns a `win32_code` for the current value of `GetLastError()`. static inline win32_code current() noexcept; }; } // namespace mixins /*! (Windows only) The implementation of the domain for Win32 error codes, those returned by `GetLastError()`. */ class _win32_code_domain : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; friend class _com_code_domain; using _base = status_code_domain; static int _win32_code_to_errno(win32::DWORD c) { switch(c) { case 0: return 0; #include "detail/win32_code_to_generic_code.ipp" } return -1; } //! Construct from a Win32 error code static _base::string_ref _make_string_ref(win32::DWORD c) noexcept { wchar_t buffer[32768]; win32::DWORD wlen = win32::FormatMessageW(0x00001000 /*FORMAT_MESSAGE_FROM_SYSTEM*/ | 0x00000200 /*FORMAT_MESSAGE_IGNORE_INSERTS*/, nullptr, c, 0, buffer, 32768, nullptr); size_t allocation = wlen + (wlen >> 1); win32::DWORD bytes; if(wlen == 0) { return _base::string_ref("failed to get message from system"); } for(;;) { auto *p = static_cast<char *>(malloc(allocation)); // NOLINT if(p == nullptr) { return _base::string_ref("failed to get message from system"); } bytes = win32::WideCharToMultiByte(65001 /*CP_UTF8*/, 0, buffer, (int) (wlen + 1), p, (int) allocation, nullptr, nullptr); if(bytes != 0) { char *end = strchr(p, 0); while(end[-1] == 10 || end[-1] == 13) { --end; } *end = 0; // NOLINT return _base::atomic_refcounted_string_ref(p, end - p); } free(p); // NOLINT if(win32::GetLastError() == 0x7a /*ERROR_INSUFFICIENT_BUFFER*/) { allocation += allocation >> 2; continue; } return _base::string_ref("failed to get message from system"); } } public: //! The value type of the win32 code, which is a `win32::DWORD` using value_type = win32::DWORD; using _base::string_ref; public: //! Default constructor constexpr explicit _win32_code_domain(typename _base::unique_id_type id = 0x8cd18ee72d680f1b) noexcept : _base(id) { } _win32_code_domain(const _win32_code_domain &) = default; _win32_code_domain(_win32_code_domain &&) = default; _win32_code_domain &operator=(const _win32_code_domain &) = default; _win32_code_domain &operator=(_win32_code_domain &&) = default; ~_win32_code_domain() = default; //! Constexpr singleton getter. Returns the constexpr win32_code_domain variable. static inline constexpr const _win32_code_domain &get(); virtual string_ref name() const noexcept override { return string_ref("win32 domain"); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); return static_cast<const win32_code &>(code).value() != 0; // NOLINT } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); const auto &c1 = static_cast<const win32_code &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const win32_code &>(code2); // NOLINT return c1.value() == c2.value(); } if(code2.domain() == generic_code_domain) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT if(static_cast<int>(c2.value()) == _win32_code_to_errno(c1.value())) { return true; } } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const win32_code &>(code); // NOLINT return generic_code(static_cast<errc>(_win32_code_to_errno(c.value()))); } virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const win32_code &>(code); // NOLINT return _make_string_ref(c.value()); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const win32_code &>(code); // NOLINT throw status_error<_win32_code_domain>(c); } #endif }; //! (Windows only) A constexpr source variable for the win32 code domain, which is that of `GetLastError()` (Windows). Returned by `_win32_code_domain::get()`. constexpr _win32_code_domain win32_code_domain; inline constexpr const _win32_code_domain &_win32_code_domain::get() { return win32_code_domain; } namespace mixins { template <class Base> inline win32_code mixin<Base, _win32_code_domain>::current() noexcept { return win32_code(win32::GetLastError()); } } // namespace mixins BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/generic_code.hpp 0000644 00000045225 15125552774 0014640 0 ustar 00 /* Proposed SG14 status_code (C) 2018 - 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License in the accompanying file Licence.txt or at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Distributed under the Boost Software License, Version 1.0. (See accompanying file Licence.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_GENERIC_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_GENERIC_CODE_HPP #include "status_error.hpp" #include <cerrno> // for error constants BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN //! The generic error coding (POSIX) enum class errc : int { success = 0, unknown = -1, address_family_not_supported = EAFNOSUPPORT, address_in_use = EADDRINUSE, address_not_available = EADDRNOTAVAIL, already_connected = EISCONN, argument_list_too_long = E2BIG, argument_out_of_domain = EDOM, bad_address = EFAULT, bad_file_descriptor = EBADF, bad_message = EBADMSG, broken_pipe = EPIPE, connection_aborted = ECONNABORTED, connection_already_in_progress = EALREADY, connection_refused = ECONNREFUSED, connection_reset = ECONNRESET, cross_device_link = EXDEV, destination_address_required = EDESTADDRREQ, device_or_resource_busy = EBUSY, directory_not_empty = ENOTEMPTY, executable_format_error = ENOEXEC, file_exists = EEXIST, file_too_large = EFBIG, filename_too_long = ENAMETOOLONG, function_not_supported = ENOSYS, host_unreachable = EHOSTUNREACH, identifier_removed = EIDRM, illegal_byte_sequence = EILSEQ, inappropriate_io_control_operation = ENOTTY, interrupted = EINTR, invalid_argument = EINVAL, invalid_seek = ESPIPE, io_error = EIO, is_a_directory = EISDIR, message_size = EMSGSIZE, network_down = ENETDOWN, network_reset = ENETRESET, network_unreachable = ENETUNREACH, no_buffer_space = ENOBUFS, no_child_process = ECHILD, no_link = ENOLINK, no_lock_available = ENOLCK, no_message = ENOMSG, no_protocol_option = ENOPROTOOPT, no_space_on_device = ENOSPC, no_stream_resources = ENOSR, no_such_device_or_address = ENXIO, no_such_device = ENODEV, no_such_file_or_directory = ENOENT, no_such_process = ESRCH, not_a_directory = ENOTDIR, not_a_socket = ENOTSOCK, not_a_stream = ENOSTR, not_connected = ENOTCONN, not_enough_memory = ENOMEM, not_supported = ENOTSUP, operation_canceled = ECANCELED, operation_in_progress = EINPROGRESS, operation_not_permitted = EPERM, operation_not_supported = EOPNOTSUPP, operation_would_block = EWOULDBLOCK, owner_dead = EOWNERDEAD, permission_denied = EACCES, protocol_error = EPROTO, protocol_not_supported = EPROTONOSUPPORT, read_only_file_system = EROFS, resource_deadlock_would_occur = EDEADLK, resource_unavailable_try_again = EAGAIN, result_out_of_range = ERANGE, state_not_recoverable = ENOTRECOVERABLE, stream_timeout = ETIME, text_file_busy = ETXTBSY, timed_out = ETIMEDOUT, too_many_files_open_in_system = ENFILE, too_many_files_open = EMFILE, too_many_links = EMLINK, too_many_symbolic_link_levels = ELOOP, value_too_large = EOVERFLOW, wrong_protocol_type = EPROTOTYPE }; namespace detail { BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline const char *generic_code_message(errc code) noexcept { switch(code) { case errc::success: return "Success"; case errc::address_family_not_supported: return "Address family not supported by protocol"; case errc::address_in_use: return "Address already in use"; case errc::address_not_available: return "Cannot assign requested address"; case errc::already_connected: return "Transport endpoint is already connected"; case errc::argument_list_too_long: return "Argument list too long"; case errc::argument_out_of_domain: return "Numerical argument out of domain"; case errc::bad_address: return "Bad address"; case errc::bad_file_descriptor: return "Bad file descriptor"; case errc::bad_message: return "Bad message"; case errc::broken_pipe: return "Broken pipe"; case errc::connection_aborted: return "Software caused connection abort"; case errc::connection_already_in_progress: return "Operation already in progress"; case errc::connection_refused: return "Connection refused"; case errc::connection_reset: return "Connection reset by peer"; case errc::cross_device_link: return "Invalid cross-device link"; case errc::destination_address_required: return "Destination address required"; case errc::device_or_resource_busy: return "Device or resource busy"; case errc::directory_not_empty: return "Directory not empty"; case errc::executable_format_error: return "Exec format error"; case errc::file_exists: return "File exists"; case errc::file_too_large: return "File too large"; case errc::filename_too_long: return "File name too long"; case errc::function_not_supported: return "Function not implemented"; case errc::host_unreachable: return "No route to host"; case errc::identifier_removed: return "Identifier removed"; case errc::illegal_byte_sequence: return "Invalid or incomplete multibyte or wide character"; case errc::inappropriate_io_control_operation: return "Inappropriate ioctl for device"; case errc::interrupted: return "Interrupted system call"; case errc::invalid_argument: return "Invalid argument"; case errc::invalid_seek: return "Illegal seek"; case errc::io_error: return "Input/output error"; case errc::is_a_directory: return "Is a directory"; case errc::message_size: return "Message too long"; case errc::network_down: return "Network is down"; case errc::network_reset: return "Network dropped connection on reset"; case errc::network_unreachable: return "Network is unreachable"; case errc::no_buffer_space: return "No buffer space available"; case errc::no_child_process: return "No child processes"; case errc::no_link: return "Link has been severed"; case errc::no_lock_available: return "No locks available"; case errc::no_message: return "No message of desired type"; case errc::no_protocol_option: return "Protocol not available"; case errc::no_space_on_device: return "No space left on device"; case errc::no_stream_resources: return "Out of streams resources"; case errc::no_such_device_or_address: return "No such device or address"; case errc::no_such_device: return "No such device"; case errc::no_such_file_or_directory: return "No such file or directory"; case errc::no_such_process: return "No such process"; case errc::not_a_directory: return "Not a directory"; case errc::not_a_socket: return "Socket operation on non-socket"; case errc::not_a_stream: return "Device not a stream"; case errc::not_connected: return "Transport endpoint is not connected"; case errc::not_enough_memory: return "Cannot allocate memory"; #if ENOTSUP != EOPNOTSUPP case errc::not_supported: return "Operation not supported"; #endif case errc::operation_canceled: return "Operation canceled"; case errc::operation_in_progress: return "Operation now in progress"; case errc::operation_not_permitted: return "Operation not permitted"; case errc::operation_not_supported: return "Operation not supported"; #if EAGAIN != EWOULDBLOCK case errc::operation_would_block: return "Resource temporarily unavailable"; #endif case errc::owner_dead: return "Owner died"; case errc::permission_denied: return "Permission denied"; case errc::protocol_error: return "Protocol error"; case errc::protocol_not_supported: return "Protocol not supported"; case errc::read_only_file_system: return "Read-only file system"; case errc::resource_deadlock_would_occur: return "Resource deadlock avoided"; case errc::resource_unavailable_try_again: return "Resource temporarily unavailable"; case errc::result_out_of_range: return "Numerical result out of range"; case errc::state_not_recoverable: return "State not recoverable"; case errc::stream_timeout: return "Timer expired"; case errc::text_file_busy: return "Text file busy"; case errc::timed_out: return "Connection timed out"; case errc::too_many_files_open_in_system: return "Too many open files in system"; case errc::too_many_files_open: return "Too many open files"; case errc::too_many_links: return "Too many links"; case errc::too_many_symbolic_link_levels: return "Too many levels of symbolic links"; case errc::value_too_large: return "Value too large for defined data type"; case errc::wrong_protocol_type: return "Protocol wrong type for socket"; default: return "unknown"; } } } // namespace detail /*! The implementation of the domain for generic status codes, those mapped by `errc` (POSIX). */ class _generic_code_domain : public status_code_domain { template <class> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; using _base = status_code_domain; public: //! The value type of the generic code, which is an `errc` as per POSIX. using value_type = errc; using string_ref = _base::string_ref; public: //! Default constructor constexpr explicit _generic_code_domain(typename _base::unique_id_type id = 0x746d6354f4f733e9) noexcept : _base(id) { } _generic_code_domain(const _generic_code_domain &) = default; _generic_code_domain(_generic_code_domain &&) = default; _generic_code_domain &operator=(const _generic_code_domain &) = default; _generic_code_domain &operator=(_generic_code_domain &&) = default; ~_generic_code_domain() = default; //! Constexpr singleton getter. Returns the constexpr generic_code_domain variable. static inline constexpr const _generic_code_domain &get(); virtual _base::string_ref name() const noexcept override { return string_ref("generic domain"); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT return static_cast<const generic_code &>(code).value() != errc::success; // NOLINT } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); // NOLINT const auto &c1 = static_cast<const generic_code &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT return c1.value() == c2.value(); } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT return static_cast<const generic_code &>(code); // NOLINT } virtual _base::string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const generic_code &>(code); // NOLINT return string_ref(detail::generic_code_message(c.value())); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const generic_code &>(code); // NOLINT throw status_error<_generic_code_domain>(c); } #endif }; //! A specialisation of `status_error` for the generic code domain. using generic_error = status_error<_generic_code_domain>; //! A constexpr source variable for the generic code domain, which is that of `errc` (POSIX). Returned by `_generic_code_domain::get()`. constexpr _generic_code_domain generic_code_domain; inline constexpr const _generic_code_domain &_generic_code_domain::get() { return generic_code_domain; } // Enable implicit construction of generic_code from errc BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline generic_code make_status_code(errc c) noexcept { return generic_code(in_place, c); } /*************************************************************************************************************/ template <class T> inline bool status_code<void>::equivalent(const status_code<T> &o) const noexcept { if(_domain && o._domain) { if(_domain->_do_equivalent(*this, o)) { return true; } if(o._domain->_do_equivalent(o, *this)) { return true; } generic_code c1 = o._domain->_generic_code(o); if(c1.value() != errc::unknown && _domain->_do_equivalent(*this, c1)) { return true; } generic_code c2 = _domain->_generic_code(*this); if(c2.value() != errc::unknown && o._domain->_do_equivalent(o, c2)) { return true; } } // If we are both empty, we are equivalent, otherwise not equivalent return (!_domain && !o._domain); } //! True if the status code's are semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator==(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept { return a.equivalent(b); } //! True if the status code's are not semantically equal via `equivalent()`. template <class DomainType1, class DomainType2> inline bool operator!=(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept { return !a.equivalent(b); } //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. template <class DomainType1, class T, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator==(const status_code<DomainType1> &a, const T &b) { return a.equivalent(make_status_code(b)); } //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. template <class T, class DomainType1, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator==(const T &a, const status_code<DomainType1> &b) { return b.equivalent(make_status_code(a)); } //! True if the status code's are not semantically equal via `equivalent()` to `make_status_code(T)`. template <class DomainType1, class T, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator!=(const status_code<DomainType1> &a, const T &b) { return !a.equivalent(make_status_code(b)); } //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. template <class T, class DomainType1, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true> // ADL makes a status code inline bool operator!=(const T &a, const status_code<DomainType1> &b) { return !b.equivalent(make_status_code(a)); } //! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`. template <class DomainType1, class T, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator==(const status_code<DomainType1> &a, const T &b) { return a.equivalent(QuickStatusCodeType(b)); } //! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`. template <class T, class DomainType1, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator==(const T &a, const status_code<DomainType1> &b) { return b.equivalent(QuickStatusCodeType(a)); } //! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`. template <class DomainType1, class T, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator!=(const status_code<DomainType1> &a, const T &b) { return !a.equivalent(QuickStatusCodeType(b)); } //! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`. template <class T, class DomainType1, // class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated > inline bool operator!=(const T &a, const status_code<DomainType1> &b) { return !b.equivalent(QuickStatusCodeType(a)); } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/config.hpp 0000644 00000037441 15125552774 0013500 0 ustar 00 /* Proposed SG14 status_code (C) 2018 - 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License in the accompanying file Licence.txt or at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Distributed under the Boost Software License, Version 1.0. (See accompanying file Licence.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_CONFIG_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_CONFIG_HPP // < 0.1 each #include <cassert> #include <cstddef> // for size_t #include <cstdlib> // for free // 0.22 #include <type_traits> // 0.29 #include <atomic> // 0.28 (0.15 of which is exception_ptr) #include <exception> // for std::exception // <new> includes <exception>, <exception> includes <new> #include <new> // 0.01 #include <initializer_list> #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 #if defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) || __cplusplus >= 201400 || _MSC_VER >= 1910 /* VS2017 */ //! Defined to be `constexpr` when on C++ 14 or better compilers. Usually automatic, can be overriden. #define BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 constexpr #else #define BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 #endif #endif #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN #if defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) || (_HAS_CXX17 && _MSC_VER >= 1911 /* VS2017.3 */) #define BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN [[noreturn]] #endif #endif #if !defined(BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN) #ifdef __has_cpp_attribute #if __has_cpp_attribute(noreturn) #define BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN [[noreturn]] #endif #endif #endif #if !defined(BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN) #if defined(_MSC_VER) #define BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN __declspec(noreturn) #elif defined(__GNUC__) #define BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN __attribute__((__noreturn__)) #else #define BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN #endif #endif // GCCs before 7 don't grok [[noreturn]] virtual functions, and warn annoyingly #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 7 #undef BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN #define BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN #endif #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD #if defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) || (_HAS_CXX17 && _MSC_VER >= 1911 /* VS2017.3 */) #define BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD [[nodiscard]] #endif #endif #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD #ifdef __has_cpp_attribute #if __has_cpp_attribute(nodiscard) #define BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD [[nodiscard]] #endif #elif defined(__clang__) #define BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD __attribute__((warn_unused_result)) #elif defined(_MSC_VER) // _Must_inspect_result_ expands into this #define BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD \ __declspec("SAL_name" \ "(" \ "\"_Must_inspect_result_\"" \ "," \ "\"\"" \ "," \ "\"2\"" \ ")") __declspec("SAL_begin") __declspec("SAL_post") __declspec("SAL_mustInspect") __declspec("SAL_post") __declspec("SAL_checkReturn") __declspec("SAL_end") #endif #endif #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD #define BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD #endif #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI #if defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) || (__clang_major__ >= 7 && !defined(__APPLE__)) //! Defined to be `[[clang::trivial_abi]]` when on a new enough clang compiler. Usually automatic, can be overriden. #define BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI [[clang::trivial_abi]] #else #define BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI #endif #endif #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE //! The system_error2 namespace name. #define BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE system_error2 //! Begins the system_error2 namespace. #define BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN \ namespace system_error2 \ { //! Ends the system_error2 namespace. #define BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END } #endif //! Namespace for the library BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN //! Namespace for user specialised traits namespace traits { /*! Specialise to true if you guarantee that a type is move bitcopying (i.e. its move constructor equals copying bits from old to new, old is left in a default constructed state, and calling the destructor on a default constructed instance is trivial). All trivially copyable types are move bitcopying by definition, and that is the unspecialised implementation. */ template <class T> struct is_move_bitcopying { static constexpr bool value = std::is_trivially_copyable<T>::value; }; } // namespace traits namespace detail { #if __cplusplus >= 201400 || _MSC_VER >= 1910 /* VS2017 */ inline constexpr size_t cstrlen(const char *str) { const char *end = nullptr; for(end = str; *end != 0; ++end) // NOLINT ; return end - str; } #else inline constexpr size_t cstrlen_(const char *str, size_t acc) { return (str[0] == 0) ? acc : cstrlen_(str + 1, acc + 1); } inline constexpr size_t cstrlen(const char *str) { return cstrlen_(str, 0); } #endif /* A partially compliant implementation of C++20's std::bit_cast function contributed by Jesse Towner. TODO FIXME Replace with C++ 20 bit_cast when available. Our bit_cast is only guaranteed to be constexpr when both the input and output arguments are either integrals or enums. However, this covers most use cases since the vast majority of status_codes have an underlying type that is either an integral or enum. We still attempt a constexpr union-based type pun for non-array input types, which some compilers accept. For array inputs, we fall back to non-constexpr memmove. */ template <class T> using is_integral_or_enum = std::integral_constant<bool, std::is_integral<T>::value || std::is_enum<T>::value>; template <class To, class From> using is_static_castable = std::integral_constant<bool, is_integral_or_enum<To>::value && is_integral_or_enum<From>::value>; template <class To, class From> using is_union_castable = std::integral_constant<bool, !is_static_castable<To, From>::value && !std::is_array<To>::value && !std::is_array<From>::value>; template <class To, class From> using is_bit_castable = std::integral_constant<bool, sizeof(To) == sizeof(From) && traits::is_move_bitcopying<To>::value && traits::is_move_bitcopying<From>::value>; template <class To, class From> union bit_cast_union { From source; To target; }; template <class To, class From, typename std::enable_if< // is_bit_castable<To, From>::value // && is_static_castable<To, From>::value // && !is_union_castable<To, From>::value, // bool>::type = true> // constexpr To bit_cast(const From &from) noexcept { return static_cast<To>(from); } #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif template <class To, class From, typename std::enable_if< // is_bit_castable<To, From>::value // && !is_static_castable<To, From>::value // && is_union_castable<To, From>::value, // bool>::type = true> // constexpr To bit_cast(const From &from) noexcept { return bit_cast_union<To, From>{from}.target; } #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif template <class To, class From, typename std::enable_if< // is_bit_castable<To, From>::value // && !is_static_castable<To, From>::value // && !is_union_castable<To, From>::value, // bool>::type = true> // To bit_cast(const From &from) noexcept { bit_cast_union<To, From> ret; memmove(&ret.source, &from, sizeof(ret.source)); return ret.target; } /* erasure_cast performs a bit_cast with additional rules to handle types of differing sizes. For integral & enum types, it may perform a narrowing or widing conversion with static_cast if necessary, before doing the final conversion with bit_cast. When casting to or from non-integral, non-enum types it may insert the value into another object with extra padding bytes to satisfy bit_cast's preconditions that both types have the same size. */ template <class To, class From> using is_erasure_castable = std::integral_constant<bool, traits::is_move_bitcopying<To>::value && traits::is_move_bitcopying<From>::value>; template <class T, bool = std::is_enum<T>::value> struct identity_or_underlying_type { using type = T; }; template <class T> struct identity_or_underlying_type<T, true> { using type = typename std::underlying_type<T>::type; }; template <class OfSize, class OfSign> using erasure_integer_type = typename std::conditional<std::is_signed<typename identity_or_underlying_type<OfSign>::type>::value, typename std::make_signed<typename identity_or_underlying_type<OfSize>::type>::type, typename std::make_unsigned<typename identity_or_underlying_type<OfSize>::type>::type>::type; template <class ErasedType, std::size_t N> struct padded_erasure_object { static_assert(traits::is_move_bitcopying<ErasedType>::value, "ErasedType must be TriviallyCopyable or MoveBitcopying"); static_assert(alignof(ErasedType) <= sizeof(ErasedType), "ErasedType must not be over-aligned"); ErasedType value; char padding[N]; constexpr explicit padded_erasure_object(const ErasedType &v) noexcept : value(v) , padding{} { } }; template <class To, class From, typename std::enable_if<is_erasure_castable<To, From>::value && (sizeof(To) == sizeof(From)), bool>::type = true> constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(from); } template <class To, class From, typename std::enable_if<is_erasure_castable<To, From>::value && is_static_castable<To, From>::value && (sizeof(To) < sizeof(From)), bool>::type = true> constexpr To erasure_cast(const From &from) noexcept { return static_cast<To>(bit_cast<erasure_integer_type<From, To>>(from)); } template <class To, class From, typename std::enable_if<is_erasure_castable<To, From>::value && is_static_castable<To, From>::value && (sizeof(To) > sizeof(From)), bool>::type = true> constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(static_cast<erasure_integer_type<To, From>>(from)); } template <class To, class From, typename std::enable_if<is_erasure_castable<To, From>::value && !is_static_castable<To, From>::value && (sizeof(To) < sizeof(From)), bool>::type = true> constexpr To erasure_cast(const From &from) noexcept { return bit_cast<padded_erasure_object<To, sizeof(From) - sizeof(To)>>(from).value; } template <class To, class From, typename std::enable_if<is_erasure_castable<To, From>::value && !is_static_castable<To, From>::value && (sizeof(To) > sizeof(From)), bool>::type = true> constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(padded_erasure_object<From, sizeof(To) - sizeof(From)>{from}); } } // namespace detail BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_FATAL #ifdef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX #error If BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX is defined, you must define your own BOOST_OUTCOME_SYSTEM_ERROR2_FATAL implementation! #endif #include <cstdlib> // for abort #ifdef __APPLE__ #include <unistd.h> // for write #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN namespace detail { namespace avoid_stdio_include { #if !defined(__APPLE__) && !defined(_MSC_VER) extern "C" ptrdiff_t write(int, const void *, size_t); #elif defined(_MSC_VER) extern ptrdiff_t write(int, const void *, size_t); #if defined(_WIN64) #pragma comment(linker, "/alternatename:?write@avoid_stdio_include@detail@system_error2@@YA_JHPEBX_K@Z=write") #else #pragma comment(linker, "/alternatename:?write@avoid_stdio_include@detail@system_error2@@YAHHPBXI@Z=_write") #endif #endif } // namespace avoid_stdio_include inline void do_fatal_exit(const char *msg) { using namespace avoid_stdio_include; write(2 /*stderr*/, msg, cstrlen(msg)); write(2 /*stderr*/, "\n", 1); abort(); } } // namespace detail BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END //! Prints msg to stderr, and calls `std::terminate()`. Can be overriden via predefinition. #define BOOST_OUTCOME_SYSTEM_ERROR2_FATAL(msg) ::BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::detail::do_fatal_exit(msg) #endif #endif experimental/status-code/getaddrinfo_code.hpp 0000644 00000014305 15125552774 0015505 0 ustar 00 /* Proposed SG14 status_code (C) 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Jan 2020 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_GETADDRINFO_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_GETADDRINFO_CODE_HPP #include "quick_status_code_from_enum.hpp" #ifdef _WIN32 #error Not available for Microsoft Windows #else #include <netdb.h> #include <sys/socket.h> #include <sys/types.h> #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN class _getaddrinfo_code_domain; //! A getaddrinfo error code, those returned by `getaddrinfo()`. using getaddrinfo_code = status_code<_getaddrinfo_code_domain>; //! A specialisation of `status_error` for the `getaddrinfo()` error code domain. using getaddrinfo_error = status_error<_getaddrinfo_code_domain>; /*! The implementation of the domain for `getaddrinfo()` error codes, those returned by `getaddrinfo()`. */ class _getaddrinfo_code_domain : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; using _base = status_code_domain; public: //! The value type of the `getaddrinfo()` code, which is an `int` using value_type = int; using _base::string_ref; //! Default constructor constexpr explicit _getaddrinfo_code_domain(typename _base::unique_id_type id = 0x5b24b2de470ff7b6) noexcept : _base(id) { } _getaddrinfo_code_domain(const _getaddrinfo_code_domain &) = default; _getaddrinfo_code_domain(_getaddrinfo_code_domain &&) = default; _getaddrinfo_code_domain &operator=(const _getaddrinfo_code_domain &) = default; _getaddrinfo_code_domain &operator=(_getaddrinfo_code_domain &&) = default; ~_getaddrinfo_code_domain() = default; //! Constexpr singleton getter. Returns constexpr getaddrinfo_code_domain variable. static inline constexpr const _getaddrinfo_code_domain &get(); virtual string_ref name() const noexcept override { return string_ref("getaddrinfo() domain"); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT return static_cast<const getaddrinfo_code &>(code).value() != 0; // NOLINT } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); // NOLINT const auto &c1 = static_cast<const getaddrinfo_code &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const getaddrinfo_code &>(code2); // NOLINT return c1.value() == c2.value(); } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const getaddrinfo_code &>(code); // NOLINT switch(c.value()) { #ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY: return errc::no_such_device_or_address; #endif case EAI_FAIL: return errc::io_error; case EAI_MEMORY: return errc::not_enough_memory; #ifdef EAI_NODATA case EAI_NODATA: return errc::no_such_device_or_address; #endif case EAI_NONAME: return errc::no_such_device_or_address; #ifdef EAI_OVERFLOW case EAI_OVERFLOW: return errc::argument_list_too_long; #endif case EAI_BADFLAGS: // fallthrough case EAI_SERVICE: return errc::invalid_argument; case EAI_FAMILY: // fallthrough case EAI_SOCKTYPE: return errc::operation_not_supported; case EAI_AGAIN: // fallthrough case EAI_SYSTEM: return errc::resource_unavailable_try_again; default: return errc::unknown; } } virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const getaddrinfo_code &>(code); // NOLINT return string_ref(gai_strerror(c.value())); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const getaddrinfo_code &>(code); // NOLINT throw status_error<_getaddrinfo_code_domain>(c); } #endif }; //! A constexpr source variable for the `getaddrinfo()` code domain, which is that of `getaddrinfo()`. Returned by `_getaddrinfo_code_domain::get()`. constexpr _getaddrinfo_code_domain getaddrinfo_code_domain; inline constexpr const _getaddrinfo_code_domain &_getaddrinfo_code_domain::get() { return getaddrinfo_code_domain; } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/error.hpp 0000644 00000005112 15125552774 0013352 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_ERROR_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_ERROR_HPP #include "errored_status_code.hpp" #include "system_code.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! An erased `system_code` which is always a failure. The closest equivalent to `std::error_code`, except it cannot be null and cannot be modified. This refines `system_code` into an `error` object meeting the requirements of [P0709 Zero-overhead deterministic exceptions](https://wg21.link/P0709). Differences from `system_code`: - Always a failure (this is checked at construction, and if not the case, the program is terminated as this is a logic error) - No default construction. - No empty state possible. - Is immutable. As with `system_code`, it remains guaranteed to be two CPU registers in size, and move bitcopying. */ using error = errored_status_code<erased<system_code::value_type>>; #ifndef NDEBUG static_assert(sizeof(error) == 2 * sizeof(void *), "error is not exactly two pointers in size!"); static_assert(traits::is_move_bitcopying<error>::value, "error is not move bitcopying!"); #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/result.hpp 0000644 00000033150 15125552774 0013542 0 ustar 00 /* A partial result based on std::variant and proposed std::error (C) 2020 Niall Douglas <http://www.nedproductions.biz/> (11 commits) File Created: Jan 2020 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_RESULT_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_RESULT_HPP #include "error.hpp" #if __cplusplus >= 201703L || _HAS_CXX17 #if __has_include(<variant>) #include <exception> #include <variant> BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN template <class T> inline constexpr std::in_place_type_t<T> in_place_type{}; template <class T> class result; //! \brief A trait for detecting result types template <class T> struct is_result : public std::false_type { }; template <class T> struct is_result<result<T>> : public std::true_type { }; /*! \brief Exception type representing the failure to retrieve an error. */ class bad_result_access : public std::exception { public: bad_result_access() = default; //! Return an explanatory string virtual const char *what() const noexcept override { return "bad result access"; } // NOLINT }; namespace detail { struct void_ { }; template <class T> using devoid = std::conditional_t<std::is_void_v<T>, void_, T>; } // namespace detail /*! \class result \brief A imperfect `result<T>` type with its error type hardcoded to `error`, only available on C++ 17 or later. Note that the proper `result<T>` type does not have the possibility of valueless by exception state. This implementation is therefore imperfect. */ template <class T> class result : protected std::variant<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::error, detail::devoid<T>> { using _base = std::variant<BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::error, detail::devoid<T>>; static_assert(!std::is_reference_v<T>, "Type cannot be a reference"); static_assert(!std::is_array_v<T>, "Type cannot be an array"); static_assert(!std::is_same_v<T, BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::error>, "Type cannot be a std::error"); // not success nor failure types struct _implicit_converting_constructor_tag { }; struct _explicit_converting_constructor_tag { }; struct _implicit_constructor_tag { }; struct _implicit_in_place_value_constructor_tag { }; struct _implicit_in_place_error_constructor_tag { }; public: //! The value type using value_type = T; //! The error type using error_type = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::error; //! The value type, if it is available, else a usefully named unusable internal type using value_type_if_enabled = detail::devoid<T>; //! Used to rebind result types template <class U> using rebind = result<U>; protected: constexpr void _check() const { if(_base::index() == 0) { std::get_if<0>(this)->throw_exception(); } } constexpr #ifdef _MSC_VER __declspec(noreturn) #elif defined(__GNUC__) || defined(__clang__) __attribute__((noreturn)) #endif void _ub() { assert(false); // NOLINT #if defined(__GNUC__) || defined(__clang__) __builtin_unreachable(); #elif defined(_MSC_VER) __assume(0); #endif } public: constexpr _base &_internal() noexcept { return *this; } constexpr const _base &_internal() const noexcept { return *this; } //! Default constructor is disabled result() = delete; //! Copy constructor result(const result &) = delete; //! Move constructor result(result &&) = default; //! Copy assignment result &operator=(const result &) = delete; //! Move assignment result &operator=(result &&) = default; //! Destructor ~result() = default; //! Implicit result converting move constructor template <class U, std::enable_if_t<std::is_convertible_v<U, T>, bool> = true> constexpr result(result<U> &&o, _implicit_converting_constructor_tag = {}) noexcept(std::is_nothrow_constructible_v<T, U>) : _base(std::move(o)) { } //! Implicit result converting copy constructor template <class U, std::enable_if_t<std::is_convertible_v<U, T>, bool> = true> constexpr result(const result<U> &o, _implicit_converting_constructor_tag = {}) noexcept(std::is_nothrow_constructible_v<T, U>) : _base(o) { } //! Explicit result converting move constructor template <class U, std::enable_if_t<std::is_constructible_v<T, U>, bool> = true> constexpr explicit result(result<U> &&o, _explicit_converting_constructor_tag = {}) noexcept(std::is_nothrow_constructible_v<T, U>) : _base(std::move(o)) { } //! Explicit result converting copy constructor template <class U, std::enable_if_t<std::is_constructible_v<T, U>, bool> = true> constexpr explicit result(const result<U> &o, _explicit_converting_constructor_tag = {}) noexcept(std::is_nothrow_constructible_v<T, U>) : _base(o) { } //! Anything which `std::variant<error, T>` will construct from, we shall implicitly construct from using _base::_base; //! Special case `in_place_type_t<void>` constexpr explicit result(std::in_place_type_t<void> /*unused*/) noexcept : _base(in_place_type<detail::void_>) { } //! Implicit in-place converting error constructor template <class Arg1, class Arg2, class... Args, // std::enable_if_t<!(std::is_constructible_v<value_type, Arg1, Arg2, Args...> && std::is_constructible_v<error_type, Arg1, Arg2, Args...>) // &&std::is_constructible_v<error_type, Arg1, Arg2, Args...>, bool> = true, long = 5> constexpr result(Arg1 &&arg1, Arg2 &&arg2, Args &&... args) noexcept(std::is_nothrow_constructible_v<error_type, Arg1, Arg2, Args...>) : _base(std::in_place_index<0>, std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Args>(args)...) { } //! Implicit in-place converting value constructor template <class Arg1, class Arg2, class... Args, // std::enable_if_t<!(std::is_constructible_v<value_type, Arg1, Arg2, Args...> && std::is_constructible_v<error_type, Arg1, Arg2, Args...>) // &&std::is_constructible_v<value_type, Arg1, Arg2, Args...>, bool> = true, int = 5> constexpr result(Arg1 &&arg1, Arg2 &&arg2, Args &&... args) noexcept(std::is_nothrow_constructible_v<value_type, Arg1, Arg2, Args...>) : _base(std::in_place_index<1>, std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Args>(args)...) { } //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`. template <class U, class... Args, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<U, Args...>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<!std::is_same<typename std::decay<U>::type, result>::value // not copy/move of self && !std::is_same<typename std::decay<U>::type, value_type>::value // not copy/move of value type && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code && std::is_constructible<error_type, MakeStatusCodeResult>::value, // ADLed status code is compatible bool>::type = true> constexpr result(U &&v, Args &&... args) noexcept(noexcept(make_status_code(std::declval<U>(), std::declval<Args>()...))) // NOLINT : _base(std::in_place_index<0>, make_status_code(static_cast<U &&>(v), static_cast<Args &&>(args)...)) { } //! Swap with another result constexpr void swap(result &o) noexcept(std::is_nothrow_swappable_v<_base>) { _base::swap(o); } //! Clone the result constexpr result clone() const { return has_value() ? result(value()) : result(error().clone()); } //! True if result has a value constexpr bool has_value() const noexcept { return _base::index() == 1; } //! True if result has a value explicit operator bool() const noexcept { return has_value(); } //! True if result has an error constexpr bool has_error() const noexcept { return _base::index() == 0; } //! Accesses the value if one exists, else calls `.error().throw_exception()`. constexpr value_type_if_enabled &value() & { _check(); return std::get<1>(*this); } //! Accesses the value if one exists, else calls `.error().throw_exception()`. constexpr const value_type_if_enabled &value() const & { _check(); return std::get<1>(*this); } //! Accesses the value if one exists, else calls `.error().throw_exception()`. constexpr value_type_if_enabled &&value() && { _check(); return std::get<1>(std::move(*this)); } //! Accesses the value if one exists, else calls `.error().throw_exception()`. constexpr const value_type_if_enabled &&value() const && { _check(); return std::get<1>(std::move(*this)); } //! Accesses the error if one exists, else throws `bad_result_access`. constexpr error_type &error() & { if(!has_error()) { #ifndef BOOST_NO_EXCEPTIONS throw bad_result_access(); #else abort(); #endif } return *std::get_if<0>(this); } //! Accesses the error if one exists, else throws `bad_result_access`. constexpr const error_type &error() const & { if(!has_error()) { #ifndef BOOST_NO_EXCEPTIONS throw bad_result_access(); #else abort(); #endif } return *std::get_if<0>(this); } //! Accesses the error if one exists, else throws `bad_result_access`. constexpr error_type &&error() && { if(!has_error()) { #ifndef BOOST_NO_EXCEPTIONS throw bad_result_access(); #else abort(); #endif } return std::move(*std::get_if<0>(this)); } //! Accesses the error if one exists, else throws `bad_result_access`. constexpr const error_type &&error() const && { if(!has_error()) { #ifndef BOOST_NO_EXCEPTIONS throw bad_result_access(); #else abort(); #endif } return std::move(*std::get_if<0>(this)); } //! Accesses the value, being UB if none exists constexpr value_type_if_enabled &assume_value() & noexcept { if(!has_value()) { _ub(); } return *std::get_if<1>(this); } //! Accesses the error, being UB if none exists constexpr const value_type_if_enabled &assume_value() const &noexcept { if(!has_value()) { _ub(); } return *std::get_if<1>(this); } //! Accesses the error, being UB if none exists constexpr value_type_if_enabled &&assume_value() && noexcept { if(!has_value()) { _ub(); } return std::move(*std::get_if<1>(this)); } //! Accesses the error, being UB if none exists constexpr const value_type_if_enabled &&assume_value() const &&noexcept { if(!has_value()) { _ub(); } return std::move(*std::get_if<1>(this)); } //! Accesses the error, being UB if none exists constexpr error_type &assume_error() & noexcept { if(!has_error()) { _ub(); } return *std::get_if<0>(this); } //! Accesses the error, being UB if none exists constexpr const error_type &assume_error() const &noexcept { if(!has_error()) { _ub(); } return *std::get_if<0>(this); } //! Accesses the error, being UB if none exists constexpr error_type &&assume_error() && noexcept { if(!has_error()) { _ub(); } return std::move(*std::get_if<0>(this)); } //! Accesses the error, being UB if none exists constexpr const error_type &&assume_error() const &&noexcept { if(!has_error()) { _ub(); } return std::move(*std::get_if<0>(this)); } }; //! True if the two results compare equal. template <class T, class U, typename = decltype(std::declval<T>() == std::declval<U>())> constexpr inline bool operator==(const result<T> &a, const result<U> &b) noexcept { const auto &x = a._internal(); return x == b; } //! True if the two results compare unequal. template <class T, class U, typename = decltype(std::declval<T>() != std::declval<U>())> constexpr inline bool operator!=(const result<T> &a, const result<U> &b) noexcept { const auto &x = a._internal(); return x != b; } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif #endif #endif experimental/status-code/nt_code.hpp 0000644 00000017714 15125552774 0013647 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NT_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_NT_CODE_HPP #if !defined(_WIN32) && !defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) #error This file should only be included on Windows #endif #include "win32_code.hpp" BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN //! \exclude namespace win32 { // A Win32 NTSTATUS using NTSTATUS = long; // A Win32 HMODULE using HMODULE = void *; // Used to retrieve where the NTDLL DLL is mapped into memory extern HMODULE __stdcall GetModuleHandleW(const wchar_t *lpModuleName); #pragma comment(lib, "kernel32.lib") #if defined(_WIN64) #pragma comment(linker, "/alternatename:?GetModuleHandleW@win32@system_error2@@YAPEAXPEB_W@Z=GetModuleHandleW") #else #pragma comment(linker, "/alternatename:?GetModuleHandleW@win32@system_error2@@YGPAXPB_W@Z=__imp__GetModuleHandleW@4") #endif } // namespace win32 class _nt_code_domain; //! (Windows only) A NT error code, those returned by NT kernel functions. using nt_code = status_code<_nt_code_domain>; //! (Windows only) A specialisation of `status_error` for the NT error code domain. using nt_error = status_error<_nt_code_domain>; /*! (Windows only) The implementation of the domain for NT error codes, those returned by NT kernel functions. */ class _nt_code_domain : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; friend class _com_code_domain; using _base = status_code_domain; static int _nt_code_to_errno(win32::NTSTATUS c) { if(c >= 0) { return 0; // success } switch(static_cast<unsigned>(c)) { #include "detail/nt_code_to_generic_code.ipp" } return -1; } static win32::DWORD _nt_code_to_win32_code(win32::NTSTATUS c) // NOLINT { if(c >= 0) { return 0; // success } switch(static_cast<unsigned>(c)) { #include "detail/nt_code_to_win32_code.ipp" } return static_cast<win32::DWORD>(-1); } //! Construct from a NT error code static _base::string_ref _make_string_ref(win32::NTSTATUS c) noexcept { wchar_t buffer[32768]; static win32::HMODULE ntdll = win32::GetModuleHandleW(L"NTDLL.DLL"); win32::DWORD wlen = win32::FormatMessageW(0x00000800 /*FORMAT_MESSAGE_FROM_HMODULE*/ | 0x00001000 /*FORMAT_MESSAGE_FROM_SYSTEM*/ | 0x00000200 /*FORMAT_MESSAGE_IGNORE_INSERTS*/, ntdll, c, (1 << 10) /*MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)*/, buffer, 32768, nullptr); size_t allocation = wlen + (wlen >> 1); win32::DWORD bytes; if(wlen == 0) { return _base::string_ref("failed to get message from system"); } for(;;) { auto *p = static_cast<char *>(malloc(allocation)); // NOLINT if(p == nullptr) { return _base::string_ref("failed to get message from system"); } bytes = win32::WideCharToMultiByte(65001 /*CP_UTF8*/, 0, buffer, (int) (wlen + 1), p, (int) allocation, nullptr, nullptr); if(bytes != 0) { char *end = strchr(p, 0); while(end[-1] == 10 || end[-1] == 13) { --end; } *end = 0; // NOLINT return _base::atomic_refcounted_string_ref(p, end - p); } free(p); // NOLINT if(win32::GetLastError() == 0x7a /*ERROR_INSUFFICIENT_BUFFER*/) { allocation += allocation >> 2; continue; } return _base::string_ref("failed to get message from system"); } } public: //! The value type of the NT code, which is a `win32::NTSTATUS` using value_type = win32::NTSTATUS; using _base::string_ref; public: //! Default constructor constexpr explicit _nt_code_domain(typename _base::unique_id_type id = 0x93f3b4487e4af25b) noexcept : _base(id) { } _nt_code_domain(const _nt_code_domain &) = default; _nt_code_domain(_nt_code_domain &&) = default; _nt_code_domain &operator=(const _nt_code_domain &) = default; _nt_code_domain &operator=(_nt_code_domain &&) = default; ~_nt_code_domain() = default; //! Constexpr singleton getter. Returns the constexpr nt_code_domain variable. static inline constexpr const _nt_code_domain &get(); virtual string_ref name() const noexcept override { return string_ref("NT domain"); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); return static_cast<const nt_code &>(code).value() < 0; // NOLINT } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); const auto &c1 = static_cast<const nt_code &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const nt_code &>(code2); // NOLINT return c1.value() == c2.value(); } if(code2.domain() == generic_code_domain) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT if(static_cast<int>(c2.value()) == _nt_code_to_errno(c1.value())) { return true; } } if(code2.domain() == win32_code_domain) { const auto &c2 = static_cast<const win32_code &>(code2); // NOLINT if(c2.value() == _nt_code_to_win32_code(c1.value())) { return true; } } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const nt_code &>(code); // NOLINT return generic_code(static_cast<errc>(_nt_code_to_errno(c.value()))); } virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const nt_code &>(code); // NOLINT return _make_string_ref(c.value()); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const nt_code &>(code); // NOLINT throw status_error<_nt_code_domain>(c); } #endif }; //! (Windows only) A constexpr source variable for the NT code domain, which is that of NT kernel functions. Returned by `_nt_code_domain::get()`. constexpr _nt_code_domain nt_code_domain; inline constexpr const _nt_code_domain &_nt_code_domain::get() { return nt_code_domain; } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/std_error_code.hpp 0000644 00000024376 15125552774 0015233 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Aug 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_STD_ERROR_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_STD_ERROR_CODE_HPP #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX #include "posix_code.hpp" #endif #if defined(_WIN32) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) #include "win32_code.hpp" #endif #include <system_error> BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN class _std_error_code_domain; //! A `status_code` representing exactly a `std::error_code` using std_error_code = status_code<_std_error_code_domain>; namespace mixins { template <class Base> struct mixin<Base, _std_error_code_domain> : public Base { using Base::Base; //! Implicit constructor from a `std::error_code` inline mixin(std::error_code ec); //! Returns the error code category inline const std::error_category &category() const noexcept; }; } // namespace mixins /*! The implementation of the domain for `std::error_code` error codes. */ class _std_error_code_domain final : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; using _base = status_code_domain; using _error_code_type = std::error_code; using _error_category_type = std::error_category; std::string _name; static _base::string_ref _make_string_ref(_error_code_type c) noexcept { try { std::string msg = c.message(); auto *p = static_cast<char *>(malloc(msg.size() + 1)); // NOLINT if(p == nullptr) { return _base::string_ref("failed to allocate message"); } memcpy(p, msg.c_str(), msg.size() + 1); return _base::atomic_refcounted_string_ref(p, msg.size()); } catch(...) { return _base::string_ref("failed to allocate message"); } } public: //! The value type of the `std::error_code` code, which stores the `int` from the `std::error_code` using value_type = int; using _base::string_ref; //! Returns the error category singleton pointer this status code domain represents const _error_category_type &error_category() const noexcept { auto ptr = 0x223a160d20de97b4 ^ this->id(); return *reinterpret_cast<const _error_category_type *>(ptr); } //! Default constructor explicit _std_error_code_domain(const _error_category_type &category) noexcept : _base(0x223a160d20de97b4 ^ reinterpret_cast<_base::unique_id_type>(&category)) , _name("std_error_code_domain(") { _name.append(category.name()); _name.push_back(')'); } _std_error_code_domain(const _std_error_code_domain &) = default; _std_error_code_domain(_std_error_code_domain &&) = default; _std_error_code_domain &operator=(const _std_error_code_domain &) = default; _std_error_code_domain &operator=(_std_error_code_domain &&) = default; ~_std_error_code_domain() = default; static inline const _std_error_code_domain *get(_error_code_type ec); virtual string_ref name() const noexcept override { return string_ref(_name.c_str(), _name.size()); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override; virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override; virtual generic_code _generic_code(const status_code<void> &code) const noexcept override; virtual string_ref _do_message(const status_code<void> &code) const noexcept override; #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override; #endif }; namespace detail { extern inline _std_error_code_domain *std_error_code_domain_from_category(const std::error_category &category) { static constexpr size_t max_items = 64; static struct storage_t { std::atomic<unsigned> _lock; union item_t { int _init; _std_error_code_domain domain; constexpr item_t() : _init(0) { } ~item_t() {} } items[max_items]; size_t count{0}; void lock() { while(_lock.exchange(1, std::memory_order_acquire) != 0) ; } void unlock() { _lock.store(0, std::memory_order_release); } storage_t() {} ~storage_t() { lock(); for(size_t n = 0; n < count; n++) { items[n].domain.~_std_error_code_domain(); } unlock(); } _std_error_code_domain *add(const std::error_category &category) { _std_error_code_domain *ret = nullptr; lock(); for(size_t n = 0; n < count; n++) { if(items[n].domain.error_category() == category) { ret = &items[n].domain; break; } } if(ret == nullptr && count < max_items) { ret = new(&items[count++].domain) _std_error_code_domain(category); } unlock(); return ret; } } storage; return storage.add(category); } } // namespace detail namespace mixins { template <class Base> inline mixin<Base, _std_error_code_domain>::mixin(std::error_code ec) : Base(typename Base::_value_type_constructor{}, _std_error_code_domain::get(ec), ec.value()) { } template <class Base> inline const std::error_category &mixin<Base, _std_error_code_domain>::category() const noexcept { const auto &domain = static_cast<const _std_error_code_domain &>(this->domain()); return domain.error_category(); }; } // namespace mixins inline const _std_error_code_domain *_std_error_code_domain::get(std::error_code ec) { auto *p = detail::std_error_code_domain_from_category(ec.category()); assert(p != nullptr); if(p == nullptr) { abort(); } return p; } inline bool _std_error_code_domain::_do_failure(const status_code<void> &code) const noexcept { assert(code.domain() == *this); return static_cast<const std_error_code &>(code).value() != 0; // NOLINT } inline bool _std_error_code_domain::_do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept { assert(code1.domain() == *this); const auto &c1 = static_cast<const std_error_code &>(code1); // NOLINT const auto &cat1 = c1.category(); // Are we comparing to another wrapped error_code? if(code2.domain() == *this) { const auto &c2 = static_cast<const std_error_code &>(code2); // NOLINT const auto &cat2 = c2.category(); // If the error code categories are identical, do literal comparison if(cat1 == cat2) { return c1.value() == c2.value(); } // Otherwise fall back onto the _generic_code comparison, which uses default_error_condition() return false; } // Am I an error code with generic category? if(cat1 == std::generic_category()) { // Convert to generic code, and compare that generic_code _c1(static_cast<errc>(c1.value())); return _c1 == code2; } // Am I an error code with system category? if(cat1 == std::system_category()) { // Convert to POSIX or Win32 code, and compare that #ifdef _WIN32 win32_code _c1((win32::DWORD) c1.value()); return _c1 == code2; #elif !defined(BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX) posix_code _c1(c1.value()); return _c1 == code2; #endif } return false; } inline generic_code _std_error_code_domain::_generic_code(const status_code<void> &code) const noexcept { assert(code.domain() == *this); const auto &c = static_cast<const std_error_code &>(code); // NOLINT // Ask my embedded error code for its mapping to std::errc, which is a subset of our generic_code errc. return generic_code(static_cast<errc>(c.category().default_error_condition(c.value()).value())); } inline _std_error_code_domain::string_ref _std_error_code_domain::_do_message(const status_code<void> &code) const noexcept { assert(code.domain() == *this); const auto &c = static_cast<const std_error_code &>(code); // NOLINT return _make_string_ref(_error_code_type(c.value(), c.category())); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN inline void _std_error_code_domain::_do_throw_exception(const status_code<void> &code) const { assert(code.domain() == *this); const auto &c = static_cast<const std_error_code &>(code); // NOLINT throw std::system_error(std::error_code(c.value(), c.category())); } #endif static_assert(sizeof(std_error_code) <= sizeof(void *) * 2, "std_error_code does not fit into a system_code!"); BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END // Enable implicit construction of `std_error_code` from `std::error_code`. namespace std { inline BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::std_error_code make_status_code(error_code c) noexcept { return BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::std_error_code(c); } } // namespace std #endif experimental/status-code/detail/nt_code_to_win32_code.ipp 0000644 00000075225 15125552774 0017631 0 ustar 00 case 0x80000002: return 0x3e6; case 0x80000005: return 0xea; case 0x80000006: return 0x12; case 0x80000007: return 0x2a3; case 0x8000000a: return 0x2a4; case 0x8000000b: return 0x56f; case 0x8000000c: return 0x2a8; case 0x8000000d: return 0x12b; case 0x8000000e: return 0x1c; case 0x8000000f: return 0x15; case 0x80000010: return 0x15; case 0x80000011: return 0xaa; case 0x80000012: return 0x103; case 0x80000013: return 0xfe; case 0x80000014: return 0xff; case 0x80000015: return 0xff; case 0x80000016: return 0x456; case 0x80000017: return 0x2a5; case 0x80000018: return 0x2a6; case 0x8000001a: return 0x103; case 0x8000001b: return 0x44d; case 0x8000001c: return 0x456; case 0x8000001d: return 0x457; case 0x8000001e: return 0x44c; case 0x8000001f: return 0x44e; case 0x80000020: return 0x2a7; case 0x80000021: return 0x44f; case 0x80000022: return 0x450; case 0x80000023: return 0x702; case 0x80000024: return 0x713; case 0x80000025: return 0x962; case 0x80000026: return 0x2aa; case 0x80000027: return 0x10f4; case 0x80000028: return 0x2ab; case 0x80000029: return 0x2ac; case 0x8000002a: return 0x2ad; case 0x8000002b: return 0x2ae; case 0x8000002c: return 0x2af; case 0x8000002d: return 0x2a9; case 0x8000002e: return 0x321; case 0x8000002f: return 0x324; case 0x80000030: return 0xab; case 0x80000032: return 0xeb; case 0x80000288: return 0x48d; case 0x80000289: return 0x48e; case 0x80000803: return 0x1abb; case 0x8000a127: return 0x3bdf; case 0x8000cf00: return 0x16e; case 0x8000cf04: return 0x16d; case 0x8000cf05: return 0x176; case 0x80130001: return 0x13c5; case 0x80130002: return 0x13c6; case 0x80130003: return 0x13c7; case 0x80130004: return 0x13c8; case 0x80130005: return 0x13c9; case 0x80190009: return 0x19e5; case 0x80190029: return 0x1aa0; case 0x80190031: return 0x1aa2; case 0x80190041: return 0x1ab3; case 0x80190042: return 0x1ab4; case 0x801c0001: return 0x7a; case 0xc0000001: return 0x1f; case 0xc0000002: return 0x1; case 0xc0000003: return 0x57; case 0xc0000004: return 0x18; case 0xc0000005: return 0x3e6; case 0xc0000006: return 0x3e7; case 0xc0000007: return 0x5ae; case 0xc0000008: return 0x6; case 0xc0000009: return 0x3e9; case 0xc000000a: return 0xc1; case 0xc000000b: return 0x57; case 0xc000000c: return 0x21d; case 0xc000000d: return 0x57; case 0xc000000e: return 0x2; case 0xc000000f: return 0x2; case 0xc0000010: return 0x1; case 0xc0000011: return 0x26; case 0xc0000012: return 0x22; case 0xc0000013: return 0x15; case 0xc0000014: return 0x6f9; case 0xc0000015: return 0x1b; case 0xc0000016: return 0xea; case 0xc0000017: return 0x8; case 0xc0000018: return 0x1e7; case 0xc0000019: return 0x1e7; case 0xc000001a: return 0x57; case 0xc000001b: return 0x57; case 0xc000001c: return 0x1; case 0xc000001e: return 0x5; case 0xc000001f: return 0x5; case 0xc0000020: return 0xc1; case 0xc0000021: return 0x5; case 0xc0000022: return 0x5; case 0xc0000023: return 0x7a; case 0xc0000024: return 0x6; case 0xc0000027: return 0x21e; case 0xc0000028: return 0x21f; case 0xc0000029: return 0x220; case 0xc000002a: return 0x9e; case 0xc000002c: return 0x1e7; case 0xc000002d: return 0x1e7; case 0xc000002e: return 0x221; case 0xc000002f: return 0x222; case 0xc0000030: return 0x57; case 0xc0000031: return 0x223; case 0xc0000032: return 0x571; case 0xc0000033: return 0x7b; case 0xc0000034: return 0x2; case 0xc0000035: return 0xb7; case 0xc0000036: return 0x72a; case 0xc0000037: return 0x6; case 0xc0000038: return 0x224; case 0xc0000039: return 0xa1; case 0xc000003a: return 0x3; case 0xc000003b: return 0xa1; case 0xc000003c: return 0x45d; case 0xc000003d: return 0x45d; case 0xc000003e: return 0x17; case 0xc000003f: return 0x17; case 0xc0000040: return 0x8; case 0xc0000041: return 0x5; case 0xc0000042: return 0x6; case 0xc0000043: return 0x20; case 0xc0000044: return 0x718; case 0xc0000045: return 0x57; case 0xc0000046: return 0x120; case 0xc0000047: return 0x12a; case 0xc0000048: return 0x57; case 0xc0000049: return 0x57; case 0xc000004a: return 0x9c; case 0xc000004b: return 0x5; case 0xc000004c: return 0x57; case 0xc000004d: return 0x57; case 0xc000004e: return 0x57; case 0xc000004f: return 0x11a; case 0xc0000050: return 0xff; case 0xc0000051: return 0x570; case 0xc0000052: return 0x570; case 0xc0000053: return 0x570; case 0xc0000054: return 0x21; case 0xc0000055: return 0x21; case 0xc0000056: return 0x5; case 0xc0000057: return 0x32; case 0xc0000058: return 0x519; case 0xc0000059: return 0x51a; case 0xc000005a: return 0x51b; case 0xc000005b: return 0x51c; case 0xc000005c: return 0x51d; case 0xc000005d: return 0x51e; case 0xc000005e: return 0x51f; case 0xc000005f: return 0x520; case 0xc0000060: return 0x521; case 0xc0000061: return 0x522; case 0xc0000062: return 0x523; case 0xc0000063: return 0x524; case 0xc0000064: return 0x525; case 0xc0000065: return 0x526; case 0xc0000066: return 0x527; case 0xc0000067: return 0x528; case 0xc0000068: return 0x529; case 0xc0000069: return 0x52a; case 0xc000006a: return 0x56; case 0xc000006b: return 0x52c; case 0xc000006c: return 0x52d; case 0xc000006d: return 0x52e; case 0xc000006e: return 0x52f; case 0xc000006f: return 0x530; case 0xc0000070: return 0x531; case 0xc0000071: return 0x532; case 0xc0000072: return 0x533; case 0xc0000073: return 0x534; case 0xc0000074: return 0x535; case 0xc0000075: return 0x536; case 0xc0000076: return 0x537; case 0xc0000077: return 0x538; case 0xc0000078: return 0x539; case 0xc0000079: return 0x53a; case 0xc000007a: return 0x7f; case 0xc000007b: return 0xc1; case 0xc000007c: return 0x3f0; case 0xc000007d: return 0x53c; case 0xc000007e: return 0x9e; case 0xc000007f: return 0x70; case 0xc0000080: return 0x53d; case 0xc0000081: return 0x53e; case 0xc0000082: return 0x44; case 0xc0000083: return 0x103; case 0xc0000084: return 0x53f; case 0xc0000085: return 0x103; case 0xc0000086: return 0x9a; case 0xc0000087: return 0xe; case 0xc0000088: return 0x1e7; case 0xc0000089: return 0x714; case 0xc000008a: return 0x715; case 0xc000008b: return 0x716; case 0xc0000095: return 0x216; case 0xc0000097: return 0x8; case 0xc0000098: return 0x3ee; case 0xc0000099: return 0x540; case 0xc000009a: return 0x5aa; case 0xc000009b: return 0x3; case 0xc000009c: return 0x17; case 0xc000009d: return 0x48f; case 0xc000009e: return 0x15; case 0xc000009f: return 0x1e7; case 0xc00000a0: return 0x1e7; case 0xc00000a1: return 0x5ad; case 0xc00000a2: return 0x13; case 0xc00000a3: return 0x15; case 0xc00000a4: return 0x541; case 0xc00000a5: return 0x542; case 0xc00000a6: return 0x543; case 0xc00000a7: return 0x544; case 0xc00000a8: return 0x545; case 0xc00000a9: return 0x57; case 0xc00000aa: return 0x225; case 0xc00000ab: return 0xe7; case 0xc00000ac: return 0xe7; case 0xc00000ad: return 0xe6; case 0xc00000ae: return 0xe7; case 0xc00000af: return 0x1; case 0xc00000b0: return 0xe9; case 0xc00000b1: return 0xe8; case 0xc00000b2: return 0x217; case 0xc00000b3: return 0x218; case 0xc00000b4: return 0xe6; case 0xc00000b5: return 0x79; case 0xc00000b6: return 0x26; case 0xc00000b7: return 0x226; case 0xc00000b8: return 0x227; case 0xc00000b9: return 0x228; case 0xc00000ba: return 0x5; case 0xc00000bb: return 0x32; case 0xc00000bc: return 0x33; case 0xc00000bd: return 0x34; case 0xc00000be: return 0x35; case 0xc00000bf: return 0x36; case 0xc00000c0: return 0x37; case 0xc00000c1: return 0x38; case 0xc00000c2: return 0x39; case 0xc00000c3: return 0x3a; case 0xc00000c4: return 0x3b; case 0xc00000c5: return 0x3c; case 0xc00000c6: return 0x3d; case 0xc00000c7: return 0x3e; case 0xc00000c8: return 0x3f; case 0xc00000c9: return 0x40; case 0xc00000ca: return 0x41; case 0xc00000cb: return 0x42; case 0xc00000cc: return 0x43; case 0xc00000cd: return 0x44; case 0xc00000ce: return 0x45; case 0xc00000cf: return 0x46; case 0xc00000d0: return 0x47; case 0xc00000d1: return 0x48; case 0xc00000d2: return 0x58; case 0xc00000d3: return 0x229; case 0xc00000d4: return 0x11; case 0xc00000d5: return 0x5; case 0xc00000d6: return 0xf0; case 0xc00000d7: return 0x546; case 0xc00000d8: return 0x22a; case 0xc00000d9: return 0xe8; case 0xc00000da: return 0x547; case 0xc00000db: return 0x22b; case 0xc00000dc: return 0x548; case 0xc00000dd: return 0x549; case 0xc00000de: return 0x54a; case 0xc00000df: return 0x54b; case 0xc00000e0: return 0x54c; case 0xc00000e1: return 0x54d; case 0xc00000e2: return 0x12c; case 0xc00000e3: return 0x12d; case 0xc00000e4: return 0x54e; case 0xc00000e5: return 0x54f; case 0xc00000e6: return 0x550; case 0xc00000e7: return 0x551; case 0xc00000e8: return 0x6f8; case 0xc00000e9: return 0x45d; case 0xc00000ea: return 0x22c; case 0xc00000eb: return 0x22d; case 0xc00000ec: return 0x22e; case 0xc00000ed: return 0x552; case 0xc00000ee: return 0x553; case 0xc00000ef: return 0x57; case 0xc00000f0: return 0x57; case 0xc00000f1: return 0x57; case 0xc00000f2: return 0x57; case 0xc00000f3: return 0x57; case 0xc00000f4: return 0x57; case 0xc00000f5: return 0x57; case 0xc00000f6: return 0x57; case 0xc00000f7: return 0x57; case 0xc00000f8: return 0x57; case 0xc00000f9: return 0x57; case 0xc00000fa: return 0x57; case 0xc00000fb: return 0x3; case 0xc00000fc: return 0x420; case 0xc00000fd: return 0x3e9; case 0xc00000fe: return 0x554; case 0xc00000ff: return 0x22f; case 0xc0000100: return 0xcb; case 0xc0000101: return 0x91; case 0xc0000102: return 0x570; case 0xc0000103: return 0x10b; case 0xc0000104: return 0x555; case 0xc0000105: return 0x556; case 0xc0000106: return 0xce; case 0xc0000107: return 0x961; case 0xc0000108: return 0x964; case 0xc000010a: return 0x5; case 0xc000010b: return 0x557; case 0xc000010c: return 0x230; case 0xc000010d: return 0x558; case 0xc000010e: return 0x420; case 0xc000010f: return 0x21a; case 0xc0000110: return 0x21a; case 0xc0000111: return 0x21a; case 0xc0000112: return 0x21a; case 0xc0000113: return 0x21a; case 0xc0000114: return 0x21a; case 0xc0000115: return 0x21a; case 0xc0000116: return 0x21a; case 0xc0000117: return 0x5a4; case 0xc0000118: return 0x231; case 0xc0000119: return 0x233; case 0xc000011a: return 0x234; case 0xc000011b: return 0xc1; case 0xc000011c: return 0x559; case 0xc000011d: return 0x55a; case 0xc000011e: return 0x3ee; case 0xc000011f: return 0x4; case 0xc0000120: return 0x3e3; case 0xc0000121: return 0x5; case 0xc0000122: return 0x4ba; case 0xc0000123: return 0x5; case 0xc0000124: return 0x55b; case 0xc0000125: return 0x55c; case 0xc0000126: return 0x55d; case 0xc0000127: return 0x55e; case 0xc0000128: return 0x6; case 0xc0000129: return 0x235; case 0xc000012a: return 0x236; case 0xc000012b: return 0x55f; case 0xc000012c: return 0x237; case 0xc000012d: return 0x5af; case 0xc000012e: return 0xc1; case 0xc000012f: return 0xc1; case 0xc0000130: return 0xc1; case 0xc0000131: return 0xc1; case 0xc0000132: return 0x238; case 0xc0000133: return 0x576; case 0xc0000134: return 0x239; case 0xc0000135: return 0x7e; case 0xc0000136: return 0x23a; case 0xc0000137: return 0x23b; case 0xc0000138: return 0xb6; case 0xc0000139: return 0x7f; case 0xc000013a: return 0x23c; case 0xc000013b: return 0x40; case 0xc000013c: return 0x40; case 0xc000013d: return 0x33; case 0xc000013e: return 0x3b; case 0xc000013f: return 0x3b; case 0xc0000140: return 0x3b; case 0xc0000141: return 0x3b; case 0xc0000142: return 0x45a; case 0xc0000143: return 0x23d; case 0xc0000144: return 0x23e; case 0xc0000145: return 0x23f; case 0xc0000146: return 0x240; case 0xc0000147: return 0x242; case 0xc0000148: return 0x7c; case 0xc0000149: return 0x56; case 0xc000014a: return 0x243; case 0xc000014b: return 0x6d; case 0xc000014c: return 0x3f1; case 0xc000014d: return 0x3f8; case 0xc000014e: return 0x244; case 0xc000014f: return 0x3ed; case 0xc0000150: return 0x45e; case 0xc0000151: return 0x560; case 0xc0000152: return 0x561; case 0xc0000153: return 0x562; case 0xc0000154: return 0x563; case 0xc0000155: return 0x564; case 0xc0000156: return 0x565; case 0xc0000157: return 0x566; case 0xc0000158: return 0x567; case 0xc0000159: return 0x3ef; case 0xc000015a: return 0x568; case 0xc000015b: return 0x569; case 0xc000015c: return 0x3f9; case 0xc000015d: return 0x56a; case 0xc000015e: return 0x245; case 0xc000015f: return 0x45d; case 0xc0000160: return 0x4db; case 0xc0000161: return 0x246; case 0xc0000162: return 0x459; case 0xc0000163: return 0x247; case 0xc0000164: return 0x248; case 0xc0000165: return 0x462; case 0xc0000166: return 0x463; case 0xc0000167: return 0x464; case 0xc0000168: return 0x465; case 0xc0000169: return 0x466; case 0xc000016a: return 0x467; case 0xc000016b: return 0x468; case 0xc000016c: return 0x45f; case 0xc000016d: return 0x45d; case 0xc000016e: return 0x249; case 0xc0000172: return 0x451; case 0xc0000173: return 0x452; case 0xc0000174: return 0x453; case 0xc0000175: return 0x454; case 0xc0000176: return 0x455; case 0xc0000177: return 0x469; case 0xc0000178: return 0x458; case 0xc000017a: return 0x56b; case 0xc000017b: return 0x56c; case 0xc000017c: return 0x3fa; case 0xc000017d: return 0x3fb; case 0xc000017e: return 0x56d; case 0xc000017f: return 0x56e; case 0xc0000180: return 0x3fc; case 0xc0000181: return 0x3fd; case 0xc0000182: return 0x57; case 0xc0000183: return 0x45d; case 0xc0000184: return 0x16; case 0xc0000185: return 0x45d; case 0xc0000186: return 0x45d; case 0xc0000187: return 0x24a; case 0xc0000188: return 0x5de; case 0xc0000189: return 0x13; case 0xc000018a: return 0x6fa; case 0xc000018b: return 0x6fb; case 0xc000018c: return 0x6fc; case 0xc000018d: return 0x6fd; case 0xc000018e: return 0x5dc; case 0xc000018f: return 0x5dd; case 0xc0000190: return 0x6fe; case 0xc0000191: return 0x24b; case 0xc0000192: return 0x700; case 0xc0000193: return 0x701; case 0xc0000194: return 0x46b; case 0xc0000195: return 0x4c3; case 0xc0000196: return 0x4c4; case 0xc0000197: return 0x5df; case 0xc0000198: return 0x70f; case 0xc0000199: return 0x710; case 0xc000019a: return 0x711; case 0xc000019b: return 0x712; case 0xc000019c: return 0x24c; case 0xc000019d: return 0x420; case 0xc000019e: return 0x130; case 0xc000019f: return 0x131; case 0xc00001a0: return 0x132; case 0xc00001a1: return 0x133; case 0xc00001a2: return 0x325; case 0xc00001a3: return 0x134; case 0xc00001a4: return 0x135; case 0xc00001a5: return 0x136; case 0xc00001a6: return 0x137; case 0xc00001a7: return 0x139; case 0xc00001a8: return 0x1abb; case 0xc00001a9: return 0x32; case 0xc00001aa: return 0x3d54; case 0xc00001ab: return 0x329; case 0xc00001ac: return 0x678; case 0xc00001ad: return 0x8; case 0xc00001ae: return 0x2f7; case 0xc00001af: return 0x32d; case 0xc0000201: return 0x41; case 0xc0000202: return 0x572; case 0xc0000203: return 0x3b; case 0xc0000204: return 0x717; case 0xc0000205: return 0x46a; case 0xc0000206: return 0x6f8; case 0xc0000207: return 0x4be; case 0xc0000208: return 0x4be; case 0xc0000209: return 0x44; case 0xc000020a: return 0x34; case 0xc000020b: return 0x40; case 0xc000020c: return 0x40; case 0xc000020d: return 0x40; case 0xc000020e: return 0x44; case 0xc000020f: return 0x3b; case 0xc0000210: return 0x3b; case 0xc0000211: return 0x3b; case 0xc0000212: return 0x3b; case 0xc0000213: return 0x3b; case 0xc0000214: return 0x3b; case 0xc0000215: return 0x3b; case 0xc0000216: return 0x32; case 0xc0000217: return 0x32; case 0xc0000218: return 0x24d; case 0xc0000219: return 0x24e; case 0xc000021a: return 0x24f; case 0xc000021b: return 0x250; case 0xc000021c: return 0x17e6; case 0xc000021d: return 0x251; case 0xc000021e: return 0x252; case 0xc000021f: return 0x253; case 0xc0000220: return 0x46c; case 0xc0000221: return 0xc1; case 0xc0000222: return 0x254; case 0xc0000223: return 0x255; case 0xc0000224: return 0x773; case 0xc0000225: return 0x490; case 0xc0000226: return 0x256; case 0xc0000227: return 0x4ff; case 0xc0000228: return 0x257; case 0xc0000229: return 0x57; case 0xc000022a: return 0x1392; case 0xc000022b: return 0x1392; case 0xc000022c: return 0x258; case 0xc000022d: return 0x4d5; case 0xc000022e: return 0x259; case 0xc000022f: return 0x25a; case 0xc0000230: return 0x492; case 0xc0000231: return 0x25b; case 0xc0000232: return 0x25c; case 0xc0000233: return 0x774; case 0xc0000234: return 0x775; case 0xc0000235: return 0x6; case 0xc0000236: return 0x4c9; case 0xc0000237: return 0x4ca; case 0xc0000238: return 0x4cb; case 0xc0000239: return 0x4cc; case 0xc000023a: return 0x4cd; case 0xc000023b: return 0x4ce; case 0xc000023c: return 0x4cf; case 0xc000023d: return 0x4d0; case 0xc000023e: return 0x4d1; case 0xc000023f: return 0x4d2; case 0xc0000240: return 0x4d3; case 0xc0000241: return 0x4d4; case 0xc0000242: return 0x25d; case 0xc0000243: return 0x4c8; case 0xc0000244: return 0x25e; case 0xc0000245: return 0x25f; case 0xc0000246: return 0x4d6; case 0xc0000247: return 0x4d7; case 0xc0000248: return 0x4d8; case 0xc0000249: return 0xc1; case 0xc0000250: return 0x260; case 0xc0000251: return 0x261; case 0xc0000252: return 0x262; case 0xc0000253: return 0x4d4; case 0xc0000254: return 0x263; case 0xc0000255: return 0x264; case 0xc0000256: return 0x265; case 0xc0000257: return 0x4d0; case 0xc0000258: return 0x266; case 0xc0000259: return 0x573; case 0xc000025a: return 0x267; case 0xc000025b: return 0x268; case 0xc000025c: return 0x269; case 0xc000025e: return 0x422; case 0xc000025f: return 0x26a; case 0xc0000260: return 0x26b; case 0xc0000261: return 0x26c; case 0xc0000262: return 0xb6; case 0xc0000263: return 0x7f; case 0xc0000264: return 0x120; case 0xc0000265: return 0x476; case 0xc0000266: return 0x26d; case 0xc0000267: return 0x10fe; case 0xc0000268: return 0x26e; case 0xc0000269: return 0x26f; case 0xc000026a: return 0x1b8e; case 0xc000026b: return 0x270; case 0xc000026c: return 0x7d1; case 0xc000026d: return 0x4b1; case 0xc000026e: return 0x15; case 0xc000026f: return 0x21c; case 0xc0000270: return 0x21c; case 0xc0000271: return 0x271; case 0xc0000272: return 0x491; case 0xc0000273: return 0x272; case 0xc0000275: return 0x1126; case 0xc0000276: return 0x1129; case 0xc0000277: return 0x112a; case 0xc0000278: return 0x1128; case 0xc0000279: return 0x780; case 0xc000027a: return 0x291; case 0xc000027b: return 0x54f; case 0xc000027c: return 0x54f; case 0xc0000280: return 0x781; case 0xc0000281: return 0xa1; case 0xc0000282: return 0x273; case 0xc0000283: return 0x488; case 0xc0000284: return 0x489; case 0xc0000285: return 0x48a; case 0xc0000286: return 0x48b; case 0xc0000287: return 0x48c; case 0xc000028a: return 0x5; case 0xc000028b: return 0x5; case 0xc000028c: return 0x284; case 0xc000028d: return 0x5; case 0xc000028e: return 0x5; case 0xc000028f: return 0x5; case 0xc0000290: return 0x5; case 0xc0000291: return 0x1777; case 0xc0000292: return 0x1778; case 0xc0000293: return 0x1772; case 0xc0000295: return 0x1068; case 0xc0000296: return 0x1069; case 0xc0000297: return 0x106a; case 0xc0000298: return 0x106b; case 0xc0000299: return 0x201a; case 0xc000029a: return 0x201b; case 0xc000029b: return 0x201c; case 0xc000029c: return 0x1; case 0xc000029d: return 0x10ff; case 0xc000029e: return 0x1100; case 0xc000029f: return 0x494; case 0xc00002a0: return 0x274; case 0xc00002a1: return 0x200a; case 0xc00002a2: return 0x200b; case 0xc00002a3: return 0x200c; case 0xc00002a4: return 0x200d; case 0xc00002a5: return 0x200e; case 0xc00002a6: return 0x200f; case 0xc00002a7: return 0x2010; case 0xc00002a8: return 0x2011; case 0xc00002a9: return 0x2012; case 0xc00002aa: return 0x2013; case 0xc00002ab: return 0x2014; case 0xc00002ac: return 0x2015; case 0xc00002ad: return 0x2016; case 0xc00002ae: return 0x2017; case 0xc00002af: return 0x2018; case 0xc00002b0: return 0x2019; case 0xc00002b1: return 0x211e; case 0xc00002b2: return 0x1127; case 0xc00002b3: return 0x275; case 0xc00002b4: return 0x276; case 0xc00002b5: return 0x277; case 0xc00002b6: return 0x651; case 0xc00002b7: return 0x49a; case 0xc00002b8: return 0x49b; case 0xc00002b9: return 0x278; case 0xc00002ba: return 0x2047; case 0xc00002c1: return 0x2024; case 0xc00002c2: return 0x279; case 0xc00002c3: return 0x575; case 0xc00002c4: return 0x27a; case 0xc00002c5: return 0x3e6; case 0xc00002c6: return 0x1075; case 0xc00002c7: return 0x1076; case 0xc00002c8: return 0x27b; case 0xc00002c9: return 0x4ed; case 0xc00002ca: return 0x10e8; case 0xc00002cb: return 0x2138; case 0xc00002cc: return 0x4e3; case 0xc00002cd: return 0x2139; case 0xc00002ce: return 0x27c; case 0xc00002cf: return 0x49d; case 0xc00002d0: return 0x213a; case 0xc00002d1: return 0x27d; case 0xc00002d2: return 0x27e; case 0xc00002d3: return 0x15; case 0xc00002d4: return 0x2141; case 0xc00002d5: return 0x2142; case 0xc00002d6: return 0x2143; case 0xc00002d7: return 0x2144; case 0xc00002d8: return 0x2145; case 0xc00002d9: return 0x2146; case 0xc00002da: return 0x2147; case 0xc00002db: return 0x2148; case 0xc00002dc: return 0x2149; case 0xc00002dd: return 0x32; case 0xc00002de: return 0x27f; case 0xc00002df: return 0x2151; case 0xc00002e0: return 0x2152; case 0xc00002e1: return 0x2153; case 0xc00002e2: return 0x2154; case 0xc00002e3: return 0x215d; case 0xc00002e4: return 0x2163; case 0xc00002e5: return 0x2164; case 0xc00002e6: return 0x2165; case 0xc00002e7: return 0x216d; case 0xc00002e8: return 0x280; case 0xc00002e9: return 0x577; case 0xc00002ea: return 0x52; case 0xc00002eb: return 0x281; case 0xc00002ec: return 0x2171; case 0xc00002ed: return 0x2172; case 0xc00002f0: return 0x2; case 0xc00002fe: return 0x45b; case 0xc00002ff: return 0x4e7; case 0xc0000300: return 0x4e6; case 0xc0000301: return 0x106f; case 0xc0000302: return 0x1074; case 0xc0000303: return 0x106e; case 0xc0000304: return 0x12e; case 0xc000030c: return 0x792; case 0xc000030d: return 0x793; case 0xc0000320: return 0x4ef; case 0xc0000321: return 0x4f0; case 0xc0000350: return 0x4e8; case 0xc0000352: return 0x177d; case 0xc0000353: return 0x282; case 0xc0000354: return 0x504; case 0xc0000355: return 0x283; case 0xc0000357: return 0x217c; case 0xc0000358: return 0x2182; case 0xc0000359: return 0xc1; case 0xc000035a: return 0xc1; case 0xc000035c: return 0x572; case 0xc000035d: return 0x4eb; case 0xc000035f: return 0x286; case 0xc0000361: return 0x4ec; case 0xc0000362: return 0x4ec; case 0xc0000363: return 0x4ec; case 0xc0000364: return 0x4ec; case 0xc0000365: return 0x287; case 0xc0000366: return 0x288; case 0xc0000368: return 0x289; case 0xc0000369: return 0x28a; case 0xc000036a: return 0x28b; case 0xc000036b: return 0x4fb; case 0xc000036c: return 0x4fb; case 0xc000036d: return 0x28c; case 0xc000036e: return 0x28d; case 0xc000036f: return 0x4fc; case 0xc0000371: return 0x21ac; case 0xc0000372: return 0x312; case 0xc0000373: return 0x8; case 0xc0000374: return 0x54f; case 0xc0000388: return 0x4f1; case 0xc000038e: return 0x28e; case 0xc0000401: return 0x78c; case 0xc0000402: return 0x78d; case 0xc0000403: return 0x78e; case 0xc0000404: return 0x217b; case 0xc0000405: return 0x219d; case 0xc0000406: return 0x219f; case 0xc0000407: return 0x28f; case 0xc0000408: return 0x52e; case 0xc0000409: return 0x502; case 0xc0000410: return 0x503; case 0xc0000411: return 0x290; case 0xc0000412: return 0x505; case 0xc0000413: return 0x78f; case 0xc0000414: return 0x506; case 0xc0000416: return 0x8; case 0xc0000417: return 0x508; case 0xc0000418: return 0x791; case 0xc0000419: return 0x215b; case 0xc000041a: return 0x21ba; case 0xc000041b: return 0x21bb; case 0xc000041c: return 0x21bc; case 0xc000041d: return 0x2c9; case 0xc0000420: return 0x29c; case 0xc0000421: return 0x219; case 0xc0000423: return 0x300; case 0xc0000424: return 0x4fb; case 0xc0000425: return 0x3fa; case 0xc0000426: return 0x301; case 0xc0000427: return 0x299; case 0xc0000428: return 0x241; case 0xc0000429: return 0x307; case 0xc000042a: return 0x308; case 0xc000042b: return 0x50c; case 0xc000042c: return 0x2e4; case 0xc0000432: return 0x509; case 0xc0000433: return 0xaa; case 0xc0000434: return 0xaa; case 0xc0000435: return 0x4c8; case 0xc0000441: return 0x1781; case 0xc0000442: return 0x1782; case 0xc0000443: return 0x1783; case 0xc0000444: return 0x1784; case 0xc0000445: return 0x1785; case 0xc0000446: return 0x513; case 0xc0000450: return 0x50b; case 0xc0000451: return 0x3b92; case 0xc0000452: return 0x3bc3; case 0xc0000453: return 0x5bb; case 0xc0000454: return 0x5be; case 0xc0000455: return 0x6; case 0xc0000456: return 0x57; case 0xc0000457: return 0x57; case 0xc0000458: return 0x57; case 0xc0000459: return 0xbea; case 0xc0000460: return 0x138; case 0xc0000461: return 0x13a; case 0xc0000462: return 0x3cfc; case 0xc0000463: return 0x13c; case 0xc0000464: return 0x141; case 0xc0000465: return 0x13b; case 0xc0000466: return 0x40; case 0xc0000467: return 0x20; case 0xc0000468: return 0x142; case 0xc0000469: return 0x3d00; case 0xc000046a: return 0x151; case 0xc000046b: return 0x152; case 0xc000046c: return 0x153; case 0xc000046d: return 0x156; case 0xc000046e: return 0x157; case 0xc000046f: return 0x158; case 0xc0000470: return 0x143; case 0xc0000471: return 0x144; case 0xc0000472: return 0x146; case 0xc0000473: return 0x14b; case 0xc0000474: return 0x147; case 0xc0000475: return 0x148; case 0xc0000476: return 0x149; case 0xc0000477: return 0x14a; case 0xc0000478: return 0x14c; case 0xc0000479: return 0x14d; case 0xc000047a: return 0x14e; case 0xc000047b: return 0x14f; case 0xc000047c: return 0x150; case 0xc000047d: return 0x5b4; case 0xc000047e: return 0x3d07; case 0xc000047f: return 0x3d08; case 0xc0000480: return 0x40; case 0xc0000481: return 0x7e; case 0xc0000482: return 0x7e; case 0xc0000483: return 0x1e3; case 0xc0000486: return 0x159; case 0xc0000487: return 0x1f; case 0xc0000488: return 0x15a; case 0xc0000489: return 0x3d0f; case 0xc000048a: return 0x32a; case 0xc000048b: return 0x32c; case 0xc000048c: return 0x15b; case 0xc000048d: return 0x15c; case 0xc000048e: return 0x162; case 0xc000048f: return 0x15d; case 0xc0000490: return 0x491; case 0xc0000491: return 0x2; case 0xc0000492: return 0x490; case 0xc0000493: return 0x492; case 0xc0000494: return 0x307; case 0xc0000495: return 0x15; case 0xc0000496: return 0x163; case 0xc0000497: return 0x3d5a; case 0xc0000499: return 0x167; case 0xc000049a: return 0x168; case 0xc000049b: return 0x12e; case 0xc000049c: return 0x169; case 0xc000049d: return 0x16f; case 0xc000049e: return 0x170; case 0xc000049f: return 0x49f; case 0xc00004a0: return 0x4a0; case 0xc00004a1: return 0x18f; case 0xc0000500: return 0x60e; case 0xc0000501: return 0x60f; case 0xc0000502: return 0x610; case 0xc0000503: return 0x15; case 0xc0000504: return 0x13f; case 0xc0000505: return 0x140; case 0xc0000506: return 0x5bf; case 0xc0000507: return 0xaa; case 0xc0000508: return 0x5e0; case 0xc0000509: return 0x5e1; case 0xc000050b: return 0x112b; case 0xc000050e: return 0x115c; case 0xc000050f: return 0x10d3; case 0xc0000510: return 0x4df; case 0xc0000511: return 0x32e; case 0xc0000512: return 0x5; case 0xc0000513: return 0x180; case 0xc0000514: return 0x115d; case 0xc0000602: return 0x675; case 0xc0000604: return 0x677; case 0xc0000606: return 0x679; case 0xc000060a: return 0x67c; case 0xc000060b: return 0x67d; case 0xc0000700: return 0x54f; case 0xc0000701: return 0x54f; case 0xc0000702: return 0x57; case 0xc0000703: return 0x54f; case 0xc0000704: return 0x32; case 0xc0000705: return 0x57; case 0xc0000706: return 0x57; case 0xc0000707: return 0x32; case 0xc0000708: return 0x54f; case 0xc0000709: return 0x30b; case 0xc000070a: return 0x6; case 0xc000070b: return 0x6; case 0xc000070c: return 0x6; case 0xc000070d: return 0x6; case 0xc000070e: return 0x6; case 0xc000070f: return 0x6; case 0xc0000710: return 0x1; case 0xc0000711: return 0x1; case 0xc0000712: return 0x50d; case 0xc0000713: return 0x310; case 0xc0000714: return 0x52e; case 0xc0000715: return 0x5b7; case 0xc0000716: return 0x7b; case 0xc0000717: return 0x459; case 0xc0000718: return 0x54f; case 0xc0000719: return 0x54f; case 0xc000071a: return 0x54f; case 0xc000071b: return 0x1; case 0xc000071c: return 0x57; case 0xc000071d: return 0x1; case 0xc000071e: return 0x1; case 0xc000071f: return 0x1; case 0xc0000720: return 0x1; case 0xc0000721: return 0x1; case 0xc0000722: return 0x72b; case 0xc0000723: return 0x1f; case 0xc0000724: return 0x1f; case 0xc0000725: return 0x1f; case 0xc0000726: return 0x1f; case 0xc0000800: return 0x30c; case 0xc0000801: return 0x21a4; case 0xc0000802: return 0x50f; case 0xc0000804: return 0x510; case 0xc0000805: return 0x1ac1; case 0xc0000806: return 0x1ac3; case 0xc0000808: return 0x319; case 0xc0000809: return 0x31a; case 0xc000080a: return 0x31b; case 0xc000080b: return 0x31c; case 0xc000080c: return 0x31d; case 0xc000080d: return 0x31e; case 0xc000080e: return 0x31f; case 0xc000080f: return 0x4d5; case 0xc0000810: return 0x328; case 0xc0000811: return 0x54f; case 0xc0000901: return 0xdc; case 0xc0000902: return 0xdd; case 0xc0000903: return 0xde; case 0xc0000904: return 0xdf; case 0xc0000905: return 0xe0; case 0xc0000906: return 0xe1; case 0xc0000907: return 0xe2; case 0xc0000908: return 0x317; case 0xc0000909: return 0x322; case 0xc0000910: return 0x326; case 0xc0009898: return 0x29e; case 0xc000a002: return 0x17; case 0xc000a003: return 0x139f; case 0xc000a004: return 0x154; case 0xc000a005: return 0x155; case 0xc000a006: return 0x32b; case 0xc000a007: return 0x32; case 0xc000a010: return 0xea; case 0xc000a011: return 0xea; case 0xc000a012: return 0x4d0; case 0xc000a013: return 0x32; case 0xc000a014: return 0x4d1; case 0xc000a080: return 0x314; case 0xc000a081: return 0x315; case 0xc000a082: return 0x316; case 0xc000a083: return 0x5b9; case 0xc000a084: return 0x5ba; case 0xc000a085: return 0x5bc; case 0xc000a086: return 0x5bd; case 0xc000a087: return 0x21bd; case 0xc000a088: return 0x21be; case 0xc000a089: return 0x21c6; case 0xc000a100: return 0x3bc4; case 0xc000a101: return 0x3bc5; case 0xc000a121: return 0x3bd9; case 0xc000a122: return 0x3bda; case 0xc000a123: return 0x3bdb; case 0xc000a124: return 0x3bdc; case 0xc000a125: return 0x3bdd; case 0xc000a126: return 0x3bde; case 0xc000a141: return 0x3c28; case 0xc000a142: return 0x3c29; case 0xc000a143: return 0x3c2a; case 0xc000a145: return 0x3c2b; case 0xc000a146: return 0x3c2c; case 0xc000a200: return 0x109a; case 0xc000a201: return 0x109c; case 0xc000a202: return 0x109d; case 0xc000a203: return 0x5; case 0xc000a281: return 0x1130; case 0xc000a282: return 0x1131; case 0xc000a283: return 0x1132; case 0xc000a284: return 0x1133; case 0xc000a285: return 0x1134; case 0xc000a2a1: return 0x1158; case 0xc000a2a2: return 0x1159; case 0xc000a2a3: return 0x115a; case 0xc000a2a4: return 0x115b; case 0xc000ce01: return 0x171; case 0xc000ce02: return 0x172; case 0xc000ce03: return 0x173; case 0xc000ce04: return 0x174; case 0xc000ce05: return 0x181; case 0xc000cf00: return 0x166; case 0xc000cf01: return 0x16a; case 0xc000cf02: return 0x16b; case 0xc000cf03: return 0x16c; case 0xc000cf06: return 0x177; case 0xc000cf07: return 0x178; case 0xc000cf08: return 0x179; case 0xc000cf09: return 0x17a; case 0xc000cf0a: return 0x17b; case 0xc000cf0b: return 0x17c; case 0xc000cf0c: return 0x17d; case 0xc000cf0d: return 0x17e; case 0xc000cf0e: return 0x17f; case 0xc000cf0f: return 0x182; case 0xc000cf10: return 0x183; case 0xc000cf11: return 0x184; case 0xc000cf12: return 0x185; case 0xc000cf13: return 0x186; case 0xc000cf14: return 0x187; case 0xc000cf15: return 0x188; case 0xc000cf16: return 0x189; case 0xc000cf17: return 0x18a; case 0xc000cf18: return 0x18b; case 0xc000cf19: return 0x18c; case 0xc000cf1a: return 0x18d; case 0xc000cf1b: return 0x18e; experimental/status-code/detail/nt_code_to_generic_code.ipp 0000644 00000006077 15125552774 0020302 0 ustar 00 case 0x80000002: return EACCES; case 0x8000000f: return EAGAIN; case 0x80000010: return EAGAIN; case 0x80000011: return EBUSY; case 0xc0000002: return ENOSYS; case 0xc0000005: return EACCES; case 0xc0000008: return EINVAL; case 0xc000000e: return ENOENT; case 0xc000000f: return ENOENT; case 0xc0000010: return ENOSYS; case 0xc0000013: return EAGAIN; case 0xc0000017: return ENOMEM; case 0xc000001c: return ENOSYS; case 0xc000001e: return EACCES; case 0xc000001f: return EACCES; case 0xc0000021: return EACCES; case 0xc0000022: return EACCES; case 0xc0000024: return EINVAL; case 0xc0000033: return EINVAL; case 0xc0000034: return ENOENT; case 0xc0000035: return EEXIST; case 0xc0000037: return EINVAL; case 0xc000003a: return ENOENT; case 0xc0000040: return ENOMEM; case 0xc0000041: return EACCES; case 0xc0000042: return EINVAL; case 0xc0000043: return EACCES; case 0xc000004b: return EACCES; case 0xc0000054: return ENOLCK; case 0xc0000055: return ENOLCK; case 0xc0000056: return EACCES; case 0xc000007f: return ENOSPC; case 0xc0000087: return ENOMEM; case 0xc0000097: return ENOMEM; case 0xc000009b: return ENOENT; case 0xc000009e: return EAGAIN; case 0xc00000a2: return EACCES; case 0xc00000a3: return EAGAIN; case 0xc00000af: return ENOSYS; case 0xc00000ba: return EACCES; case 0xc00000c0: return ENODEV; case 0xc00000d4: return EXDEV; case 0xc00000d5: return EACCES; case 0xc00000fb: return ENOENT; case 0xc0000101: return ENOTEMPTY; case 0xc0000103: return EINVAL; case 0xc0000107: return EBUSY; case 0xc0000108: return EBUSY; case 0xc000010a: return EACCES; case 0xc000011f: return EMFILE; case 0xc0000120: return ECANCELED; case 0xc0000121: return EACCES; case 0xc0000123: return EACCES; case 0xc0000128: return EINVAL; case 0xc0000189: return EACCES; case 0xc00001ad: return ENOMEM; case 0xc000022d: return EAGAIN; case 0xc0000235: return EINVAL; case 0xc000026e: return EAGAIN; case 0xc000028a: return EACCES; case 0xc000028b: return EACCES; case 0xc000028d: return EACCES; case 0xc000028e: return EACCES; case 0xc000028f: return EACCES; case 0xc0000290: return EACCES; case 0xc000029c: return ENOSYS; case 0xc00002c5: return EACCES; case 0xc00002d3: return EAGAIN; case 0xc00002ea: return EACCES; case 0xc00002f0: return ENOENT; case 0xc0000373: return ENOMEM; case 0xc0000416: return ENOMEM; case 0xc0000433: return EBUSY; case 0xc0000434: return EBUSY; case 0xc0000455: return EINVAL; case 0xc0000467: return EACCES; case 0xc0000491: return ENOENT; case 0xc0000495: return EAGAIN; case 0xc0000503: return EAGAIN; case 0xc0000507: return EBUSY; case 0xc0000512: return EACCES; case 0xc000070a: return EINVAL; case 0xc000070b: return EINVAL; case 0xc000070c: return EINVAL; case 0xc000070d: return EINVAL; case 0xc000070e: return EINVAL; case 0xc000070f: return EINVAL; case 0xc0000710: return ENOSYS; case 0xc0000711: return ENOSYS; case 0xc0000716: return EINVAL; case 0xc000071b: return ENOSYS; case 0xc000071d: return ENOSYS; case 0xc000071e: return ENOSYS; case 0xc000071f: return ENOSYS; case 0xc0000720: return ENOSYS; case 0xc0000721: return ENOSYS; case 0xc000080f: return EAGAIN; case 0xc000a203: return EACCES; experimental/status-code/detail/win32_code_to_generic_code.ipp 0000644 00000004065 15125552774 0020616 0 ustar 00 case 0x1: return ENOSYS; case 0x2: return ENOENT; case 0x3: return ENOENT; case 0x4: return EMFILE; case 0x5: return EACCES; case 0x6: return EINVAL; case 0x8: return ENOMEM; case 0xc: return EACCES; case 0xe: return ENOMEM; case 0xf: return ENODEV; case 0x10: return EACCES; case 0x11: return EXDEV; case 0x13: return EACCES; case 0x14: return ENODEV; case 0x15: return EAGAIN; case 0x19: return EIO; case 0x1d: return EIO; case 0x1e: return EIO; case 0x20: return EACCES; case 0x21: return ENOLCK; case 0x27: return ENOSPC; case 0x37: return ENODEV; case 0x50: return EEXIST; case 0x52: return EACCES; case 0x57: return EINVAL; case 0x6e: return EIO; case 0x6f: return ENAMETOOLONG; case 0x70: return ENOSPC; case 0x7b: return EINVAL; case 0x83: return EINVAL; case 0x8e: return EBUSY; case 0x91: return ENOTEMPTY; case 0xaa: return EBUSY; case 0xb7: return EEXIST; case 0xd4: return ENOLCK; case 0x10b: return EINVAL; case 0x3e3: return ECANCELED; case 0x3e6: return EACCES; case 0x3f3: return EIO; case 0x3f4: return EIO; case 0x3f5: return EIO; case 0x4d5: return EAGAIN; case 0x961: return EBUSY; case 0x964: return EBUSY; case 0x2714: return EINTR; case 0x2719: return EBADF; case 0x271d: return EACCES; case 0x271e: return EFAULT; case 0x2726: return EINVAL; case 0x2728: return EMFILE; case 0x2733: return EWOULDBLOCK; case 0x2734: return EINPROGRESS; case 0x2735: return EALREADY; case 0x2736: return ENOTSOCK; case 0x2737: return EDESTADDRREQ; case 0x2738: return EMSGSIZE; case 0x2739: return EPROTOTYPE; case 0x273a: return ENOPROTOOPT; case 0x273b: return EPROTONOSUPPORT; case 0x273d: return EOPNOTSUPP; case 0x273f: return EAFNOSUPPORT; case 0x2740: return EADDRINUSE; case 0x2741: return EADDRNOTAVAIL; case 0x2742: return ENETDOWN; case 0x2743: return ENETUNREACH; case 0x2744: return ENETRESET; case 0x2745: return ECONNABORTED; case 0x2746: return ECONNRESET; case 0x2747: return ENOBUFS; case 0x2748: return EISCONN; case 0x2749: return ENOTCONN; case 0x274c: return ETIMEDOUT; case 0x274d: return ECONNREFUSED; case 0x274f: return ENAMETOOLONG; case 0x2751: return EHOSTUNREACH; experimental/status-code/iostream_support.hpp 0000644 00000005742 15125552774 0015651 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_IOSTREAM_SUPPORT_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_IOSTREAM_SUPPORT_HPP #include "error.hpp" #include <ostream> BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! Print the status code to a `std::ostream &`. Requires that `DomainType::value_type` implements an `operator<<` overload for `std::ostream`. */ template <class DomainType, // typename std::enable_if<std::is_same<std::ostream, typename std::decay<decltype(std::declval<std::ostream>() << std::declval<typename status_code<DomainType>::value_type>())>::type>::value, bool>::type = true> inline std::ostream &operator<<(std::ostream &s, const status_code<DomainType> &v) { if(v.empty()) { return s << "(empty)"; } return s << v.domain().name().c_str() << ": " << v.value(); } /*! Print a status code domain's `string_ref` to a `std::ostream &`. */ inline std::ostream &operator<<(std::ostream &s, const status_code_domain::string_ref &v) { return s << v.c_str(); } /*! Print the erased status code to a `std::ostream &`. */ template <class ErasedType> inline std::ostream &operator<<(std::ostream &s, const status_code<erased<ErasedType>> &v) { if(v.empty()) { return s << "(empty)"; } return s << v.domain().name() << ": " << v.message(); } /*! Print the generic code to a `std::ostream &`. */ inline std::ostream &operator<<(std::ostream &s, const generic_code &v) { if(v.empty()) { return s << "(empty)"; } return s << v.domain().name() << ": " << v.message(); } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/system_code.hpp 0000644 00000005152 15125552774 0014543 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_SYSTEM_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_SYSTEM_CODE_HPP #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX #include "posix_code.hpp" #else #include "quick_status_code_from_enum.hpp" #endif #if defined(_WIN32) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) #include "nt_code.hpp" #include "win32_code.hpp" // NOT "com_code.hpp" #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! An erased-mutable status code suitably large for all the system codes which can be returned on this system. For Windows, these might be: - `com_code` (`HRESULT`) [you need to include "com_code.hpp" explicitly for this] - `nt_code` (`LONG`) - `win32_code` (`DWORD`) For POSIX, `posix_code` is possible. You are guaranteed that `system_code` can be transported by the compiler in exactly two CPU registers. */ using system_code = status_code<erased<intptr_t>>; #ifndef NDEBUG static_assert(sizeof(system_code) == 2 * sizeof(void *), "system_code is not exactly two pointers in size!"); static_assert(traits::is_move_bitcopying<system_code>::value, "system_code is not move bitcopying!"); #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/posix_code.hpp 0000644 00000015163 15125552774 0014364 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_POSIX_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_POSIX_CODE_HPP #ifdef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX #error <posix_code.hpp> is not includable when BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX is defined! #endif #include "quick_status_code_from_enum.hpp" #include <cstring> // for strchr and strerror_r BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN class _posix_code_domain; //! A POSIX error code, those returned by `errno`. using posix_code = status_code<_posix_code_domain>; //! A specialisation of `status_error` for the POSIX error code domain. using posix_error = status_error<_posix_code_domain>; namespace mixins { template <class Base> struct mixin<Base, _posix_code_domain> : public Base { using Base::Base; //! Returns a `posix_code` for the current value of `errno`. static posix_code current() noexcept; }; } // namespace mixins /*! The implementation of the domain for POSIX error codes, those returned by `errno`. */ class _posix_code_domain : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; using _base = status_code_domain; static _base::string_ref _make_string_ref(int c) noexcept { char buffer[1024] = ""; #ifdef _WIN32 strerror_s(buffer, sizeof(buffer), c); #elif defined(__gnu_linux__) && !defined(__ANDROID__) // handle glibc's weird strerror_r() char *s = strerror_r(c, buffer, sizeof(buffer)); // NOLINT if(s != nullptr) { strncpy(buffer, s, sizeof(buffer)); // NOLINT buffer[1023] = 0; } #else strerror_r(c, buffer, sizeof(buffer)); #endif size_t length = strlen(buffer); // NOLINT auto *p = static_cast<char *>(malloc(length + 1)); // NOLINT if(p == nullptr) { return _base::string_ref("failed to get message from system"); } memcpy(p, buffer, length + 1); // NOLINT return _base::atomic_refcounted_string_ref(p, length); } public: //! The value type of the POSIX code, which is an `int` using value_type = int; using _base::string_ref; //! Default constructor constexpr explicit _posix_code_domain(typename _base::unique_id_type id = 0xa59a56fe5f310933) noexcept : _base(id) { } _posix_code_domain(const _posix_code_domain &) = default; _posix_code_domain(_posix_code_domain &&) = default; _posix_code_domain &operator=(const _posix_code_domain &) = default; _posix_code_domain &operator=(_posix_code_domain &&) = default; ~_posix_code_domain() = default; //! Constexpr singleton getter. Returns constexpr posix_code_domain variable. static inline constexpr const _posix_code_domain &get(); virtual string_ref name() const noexcept override { return string_ref("posix domain"); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT return static_cast<const posix_code &>(code).value() != 0; // NOLINT } virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); // NOLINT const auto &c1 = static_cast<const posix_code &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const posix_code &>(code2); // NOLINT return c1.value() == c2.value(); } if(code2.domain() == generic_code_domain) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT if(static_cast<int>(c2.value()) == c1.value()) { return true; } } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const posix_code &>(code); // NOLINT return generic_code(static_cast<errc>(c.value())); } virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const posix_code &>(code); // NOLINT return _make_string_ref(c.value()); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); // NOLINT const auto &c = static_cast<const posix_code &>(code); // NOLINT throw status_error<_posix_code_domain>(c); } #endif }; //! A constexpr source variable for the POSIX code domain, which is that of `errno`. Returned by `_posix_code_domain::get()`. constexpr _posix_code_domain posix_code_domain; inline constexpr const _posix_code_domain &_posix_code_domain::get() { return posix_code_domain; } namespace mixins { template <class Base> inline posix_code mixin<Base, _posix_code_domain>::current() noexcept { return posix_code(errno); } } // namespace mixins BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/system_code_from_exception.hpp 0000644 00000010150 15125552774 0017636 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: June 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_SYSTEM_CODE_FROM_EXCEPTION_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_SYSTEM_CODE_FROM_EXCEPTION_HPP #include "system_code.hpp" #include <exception> // for exception_ptr #include <stdexcept> // for the exception types #include <system_error> // for std::system_error BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! A utility function which returns the closest matching system_code to a supplied exception ptr. */ inline system_code system_code_from_exception(std::exception_ptr &&ep = std::current_exception(), system_code not_matched = generic_code(errc::resource_unavailable_try_again)) noexcept { if(!ep) { return generic_code(errc::success); } try { std::rethrow_exception(ep); } catch(const std::invalid_argument & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::invalid_argument); } catch(const std::domain_error & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::argument_out_of_domain); } catch(const std::length_error & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::argument_list_too_long); } catch(const std::out_of_range & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::result_out_of_range); } catch(const std::logic_error & /*unused*/) /* base class for this group */ { ep = std::exception_ptr(); return generic_code(errc::invalid_argument); } catch(const std::system_error &e) /* also catches ios::failure */ { ep = std::exception_ptr(); if(e.code().category() == std::generic_category()) { return generic_code(static_cast<errc>(static_cast<int>(e.code().value()))); } if(e.code().category() == std::system_category()) { #ifdef _WIN32 return win32_code(e.code().value()); #else return posix_code(e.code().value()); #endif } // Don't know this error code category, can't wrap it into std_error_code // as its payload won't fit into system_code, so fall through. } catch(const std::overflow_error & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::value_too_large); } catch(const std::range_error & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::result_out_of_range); } catch(const std::runtime_error & /*unused*/) /* base class for this group */ { ep = std::exception_ptr(); return generic_code(errc::resource_unavailable_try_again); } catch(const std::bad_alloc & /*unused*/) { ep = std::exception_ptr(); return generic_code(errc::not_enough_memory); } catch(...) { } return not_matched; } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/status_code_domain.hpp 0000644 00000043223 15125552774 0016072 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_CODE_DOMAIN_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_CODE_DOMAIN_HPP #include "config.hpp" #include <cstring> // for strchr BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! The main workhorse of the system_error2 library, can be typed (`status_code<DomainType>`), erased-immutable (`status_code<void>`) or erased-mutable (`status_code<erased<T>>`). Be careful of placing these into containers! Equality and inequality operators are *semantic* not exact. Therefore two distinct items will test true! To help prevent surprise on this, `operator<` and `std::hash<>` are NOT implemented in order to trap potential incorrectness. Define your own custom comparison functions for your container which perform exact comparisons. */ template <class DomainType> class status_code; class _generic_code_domain; //! The generic code is a status code with the generic code domain, which is that of `errc` (POSIX). using generic_code = status_code<_generic_code_domain>; namespace detail { template <class StatusCode> class indirecting_domain; template <class T> struct status_code_sizer { void *a; T b; }; template <class To, class From> struct type_erasure_is_safe { static constexpr bool value = traits::is_move_bitcopying<From>::value // && (sizeof(status_code_sizer<From>) <= sizeof(status_code_sizer<To>)); }; /* We are severely limited by needing to retain C++ 11 compatibility when doing constexpr string parsing. MSVC lets you throw exceptions within a constexpr evaluation context when exceptions are globally disabled, but won't let you divide by zero, even if never evaluated, ever in constexpr. GCC and clang won't let you throw exceptions, ever, if exceptions are globally disabled. So let's use the trick of divide by zero in constexpr on GCC and clang if and only if exceptions are globally disabled. */ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdiv-by-zero" #endif #if defined(__cpp_exceptions) || (defined(_MSC_VER) && !defined(__clang__)) #define BOOST_OUTCOME_SYSTEM_ERROR2_FAIL_CONSTEXPR(msg) throw msg #else #define BOOST_OUTCOME_SYSTEM_ERROR2_FAIL_CONSTEXPR(msg) ((void) msg, 1 / 0) #endif constexpr inline unsigned long long parse_hex_byte(char c) { return ('0' <= c && c <= '9') ? (c - '0') : ('a' <= c && c <= 'f') ? (10 + c - 'a') : ('A' <= c && c <= 'F') ? (10 + c - 'A') : BOOST_OUTCOME_SYSTEM_ERROR2_FAIL_CONSTEXPR("Invalid character in UUID"); } constexpr inline unsigned long long parse_uuid2(const char *s) { return ((parse_hex_byte(s[0]) << 0) | (parse_hex_byte(s[1]) << 4) | (parse_hex_byte(s[2]) << 8) | (parse_hex_byte(s[3]) << 12) | (parse_hex_byte(s[4]) << 16) | (parse_hex_byte(s[5]) << 20) | (parse_hex_byte(s[6]) << 24) | (parse_hex_byte(s[7]) << 28) | (parse_hex_byte(s[9]) << 32) | (parse_hex_byte(s[10]) << 36) | (parse_hex_byte(s[11]) << 40) | (parse_hex_byte(s[12]) << 44) | (parse_hex_byte(s[14]) << 48) | (parse_hex_byte(s[15]) << 52) | (parse_hex_byte(s[16]) << 56) | (parse_hex_byte(s[17]) << 60)) // ^ // ((parse_hex_byte(s[19]) << 0) | (parse_hex_byte(s[20]) << 4) | (parse_hex_byte(s[21]) << 8) | (parse_hex_byte(s[22]) << 12) | (parse_hex_byte(s[24]) << 16) | (parse_hex_byte(s[25]) << 20) | (parse_hex_byte(s[26]) << 24) | (parse_hex_byte(s[27]) << 28) | (parse_hex_byte(s[28]) << 32) | (parse_hex_byte(s[29]) << 36) | (parse_hex_byte(s[30]) << 40) | (parse_hex_byte(s[31]) << 44) | (parse_hex_byte(s[32]) << 48) | (parse_hex_byte(s[33]) << 52) | (parse_hex_byte(s[34]) << 56) | (parse_hex_byte(s[35]) << 60)); } template <size_t N> constexpr inline unsigned long long parse_uuid_from_array(const char (&uuid)[N]) { return (N == 37) ? parse_uuid2(uuid) : ((N == 39) ? parse_uuid2(uuid + 1) : BOOST_OUTCOME_SYSTEM_ERROR2_FAIL_CONSTEXPR("UUID does not have correct length")); } template <size_t N> constexpr inline unsigned long long parse_uuid_from_pointer(const char *uuid) { return (N == 36) ? parse_uuid2(uuid) : ((N == 38) ? parse_uuid2(uuid + 1) : BOOST_OUTCOME_SYSTEM_ERROR2_FAIL_CONSTEXPR("UUID does not have correct length")); } #ifdef __GNUC__ #pragma GCC diagnostic pop #endif static constexpr unsigned long long test_uuid_parse = parse_uuid_from_array("430f1201-94fc-06c7-430f-120194fc06c7"); //static constexpr unsigned long long test_uuid_parse2 = parse_uuid_from_array("x30f1201-94fc-06c7-430f-120194fc06c7"); } // namespace detail /*! Abstract base class for a coding domain of a status code. */ class status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class indirecting_domain; public: //! Type of the unique id for this domain. using unique_id_type = unsigned long long; /*! (Potentially thread safe) Reference to a message string. Be aware that you cannot add payload to implementations of this class. You get exactly the `void *[3]` array to keep state, this is usually sufficient for a `std::shared_ptr<>` or a `std::string`. You can install a handler to be called when this object is copied, moved and destructed. This takes the form of a C function pointer. */ class string_ref { public: //! The value type using value_type = const char; //! The size type using size_type = size_t; //! The pointer type using pointer = const char *; //! The const pointer type using const_pointer = const char *; //! The iterator type using iterator = const char *; //! The const iterator type using const_iterator = const char *; protected: //! The operation occurring enum class _thunk_op { copy, move, destruct }; //! The prototype of the handler function. Copies can throw, moves and destructs cannot. using _thunk_spec = void (*)(string_ref *dest, const string_ref *src, _thunk_op op); #ifndef NDEBUG private: static void _checking_string_thunk(string_ref *dest, const string_ref *src, _thunk_op /*unused*/) noexcept { (void) dest; (void) src; assert(dest->_thunk == _checking_string_thunk); // NOLINT assert(src == nullptr || src->_thunk == _checking_string_thunk); // NOLINT // do nothing } protected: #endif //! Pointers to beginning and end of character range pointer _begin{}, _end{}; //! Three `void*` of state void *_state[3]{}; // at least the size of a shared_ptr //! Handler for when operations occur const _thunk_spec _thunk{nullptr}; constexpr explicit string_ref(_thunk_spec thunk) noexcept : _thunk(thunk) { } public: //! Construct from a C string literal BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 explicit string_ref(const char *str, size_type len = static_cast<size_type>(-1), void *state0 = nullptr, void *state1 = nullptr, void *state2 = nullptr, #ifndef NDEBUG _thunk_spec thunk = _checking_string_thunk #else _thunk_spec thunk = nullptr #endif ) noexcept : _begin(str) , _end((len == static_cast<size_type>(-1)) ? (str + detail::cstrlen(str)) : (str + len)) , // NOLINT _state{state0, state1, state2} , _thunk(thunk) { } //! Copy construct the derived implementation. string_ref(const string_ref &o) : _begin(o._begin) , _end(o._end) , _state{o._state[0], o._state[1], o._state[2]} , _thunk(o._thunk) { if(_thunk != nullptr) { _thunk(this, &o, _thunk_op::copy); } } //! Move construct the derived implementation. string_ref(string_ref &&o) noexcept : _begin(o._begin) , _end(o._end) , _state{o._state[0], o._state[1], o._state[2]} , _thunk(o._thunk) { if(_thunk != nullptr) { _thunk(this, &o, _thunk_op::move); } } //! Copy assignment string_ref &operator=(const string_ref &o) { if(this != &o) { #if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) string_ref temp(static_cast<string_ref &&>(*this)); this->~string_ref(); try { new(this) string_ref(o); // may throw } catch(...) { new(this) string_ref(static_cast<string_ref &&>(temp)); throw; } #else this->~string_ref(); new(this) string_ref(o); #endif } return *this; } //! Move assignment string_ref &operator=(string_ref &&o) noexcept { if(this != &o) { this->~string_ref(); new(this) string_ref(static_cast<string_ref &&>(o)); } return *this; } //! Destruction ~string_ref() { if(_thunk != nullptr) { _thunk(this, nullptr, _thunk_op::destruct); } _begin = _end = nullptr; } //! Returns whether the reference is empty or not BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD bool empty() const noexcept { return _begin == _end; } //! Returns the size of the string size_type size() const noexcept { return _end - _begin; } //! Returns a null terminated C string const_pointer c_str() const noexcept { return _begin; } //! Returns a null terminated C string const_pointer data() const noexcept { return _begin; } //! Returns the beginning of the string iterator begin() noexcept { return _begin; } //! Returns the beginning of the string const_iterator begin() const noexcept { return _begin; } //! Returns the beginning of the string const_iterator cbegin() const noexcept { return _begin; } //! Returns the end of the string iterator end() noexcept { return _end; } //! Returns the end of the string const_iterator end() const noexcept { return _end; } //! Returns the end of the string const_iterator cend() const noexcept { return _end; } }; /*! A reference counted, threadsafe reference to a message string. */ class atomic_refcounted_string_ref : public string_ref { struct _allocated_msg { mutable std::atomic<unsigned> count{1}; }; _allocated_msg *&_msg() noexcept { return reinterpret_cast<_allocated_msg *&>(this->_state[0]); } // NOLINT const _allocated_msg *_msg() const noexcept { return reinterpret_cast<const _allocated_msg *>(this->_state[0]); } // NOLINT static void _refcounted_string_thunk(string_ref *_dest, const string_ref *_src, _thunk_op op) noexcept { auto dest = static_cast<atomic_refcounted_string_ref *>(_dest); // NOLINT auto src = static_cast<const atomic_refcounted_string_ref *>(_src); // NOLINT (void) src; assert(dest->_thunk == _refcounted_string_thunk); // NOLINT assert(src == nullptr || src->_thunk == _refcounted_string_thunk); // NOLINT switch(op) { case _thunk_op::copy: { if(dest->_msg() != nullptr) { auto count = dest->_msg()->count.fetch_add(1, std::memory_order_relaxed); (void) count; assert(count != 0); // NOLINT } return; } case _thunk_op::move: { assert(src); // NOLINT auto msrc = const_cast<atomic_refcounted_string_ref *>(src); // NOLINT msrc->_begin = msrc->_end = nullptr; msrc->_state[0] = msrc->_state[1] = msrc->_state[2] = nullptr; return; } case _thunk_op::destruct: { if(dest->_msg() != nullptr) { auto count = dest->_msg()->count.fetch_sub(1, std::memory_order_release); if(count == 1) { std::atomic_thread_fence(std::memory_order_acquire); free((void *) dest->_begin); // NOLINT delete dest->_msg(); // NOLINT } } } } } public: //! Construct from a C string literal allocated using `malloc()`. explicit atomic_refcounted_string_ref(const char *str, size_type len = static_cast<size_type>(-1), void *state1 = nullptr, void *state2 = nullptr) noexcept : string_ref(str, len, new(std::nothrow) _allocated_msg, state1, state2, _refcounted_string_thunk) { if(_msg() == nullptr) { free((void *) this->_begin); // NOLINT _msg() = nullptr; // disabled this->_begin = "failed to get message from system"; this->_end = strchr(this->_begin, 0); return; } } }; private: unique_id_type _id; protected: /*! Use [https://www.random.org/cgi-bin/randbyte?nbytes=8&format=h](https://www.random.org/cgi-bin/randbyte?nbytes=8&format=h) to get a random 64 bit id. Do NOT make up your own value. Do NOT use zero. */ constexpr explicit status_code_domain(unique_id_type id) noexcept : _id(id) { } /*! UUID constructor, where input is constexpr parsed into a `unique_id_type`. */ template <size_t N> constexpr explicit status_code_domain(const char (&uuid)[N]) noexcept : _id(detail::parse_uuid_from_array<N>(uuid)) { } template <size_t N> struct _uuid_size { }; //! Alternative UUID constructor template <size_t N> constexpr explicit status_code_domain(const char *uuid, _uuid_size<N> /*unused*/) noexcept : _id(detail::parse_uuid_from_pointer<N>(uuid)) { } //! No public copying at type erased level status_code_domain(const status_code_domain &) = default; //! No public moving at type erased level status_code_domain(status_code_domain &&) = default; //! No public assignment at type erased level status_code_domain &operator=(const status_code_domain &) = default; //! No public assignment at type erased level status_code_domain &operator=(status_code_domain &&) = default; //! No public destruction at type erased level ~status_code_domain() = default; public: //! True if the unique ids match. constexpr bool operator==(const status_code_domain &o) const noexcept { return _id == o._id; } //! True if the unique ids do not match. constexpr bool operator!=(const status_code_domain &o) const noexcept { return _id != o._id; } //! True if this unique is lower than the other's unique id. constexpr bool operator<(const status_code_domain &o) const noexcept { return _id < o._id; } //! Returns the unique id used to identify identical category instances. constexpr unique_id_type id() const noexcept { return _id; } //! Name of this category. virtual string_ref name() const noexcept = 0; protected: //! True if code means failure. virtual bool _do_failure(const status_code<void> &code) const noexcept = 0; //! True if code is (potentially non-transitively) equivalent to another code in another domain. virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept = 0; //! Returns the generic code closest to this code, if any. virtual generic_code _generic_code(const status_code<void> &code) const noexcept = 0; //! Return a reference to a string textually representing a code. virtual string_ref _do_message(const status_code<void> &code) const noexcept = 0; #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) //! Throw a code as a C++ exception. BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const = 0; #else // Keep a vtable slot for binary compatibility BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> & /*code*/) const { abort(); } #endif // For a `status_code<erased<T>>` only, copy from `src` to `dst`. Default implementation uses `memcpy()`. virtual void _do_erased_copy(status_code<void> &dst, const status_code<void> &src, size_t bytes) const { memcpy(&dst, &src, bytes); } // NOLINT // For a `status_code<erased<T>>` only, destroy the erased value type. Default implementation does nothing. virtual void _do_erased_destroy(status_code<void> &code, size_t bytes) const noexcept // NOLINT { (void) code; (void) bytes; } }; BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/com_code.hpp 0000644 00000022002 15125552774 0013766 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_COM_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_COM_CODE_HPP #if !defined(_WIN32) && !defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) #error This file should only be included on Windows #endif #include "nt_code.hpp" #include "win32_code.hpp" #ifndef BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE #include <comdef.h> #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN class _com_code_domain; /*! (Windows only) A COM error code. Note semantic equivalence testing is only implemented for `FACILITY_WIN32` and `FACILITY_NT_BIT`. As you can see at [https://blogs.msdn.microsoft.com/eldar/2007/04/03/a-lot-of-hresult-codes/](https://blogs.msdn.microsoft.com/eldar/2007/04/03/a-lot-of-hresult-codes/), there are an awful lot of COM error codes, and keeping mapping tables for all of them would be impractical (for the Win32 and NT facilities, we actually reuse the mapping tables in `win32_code` and `nt_code`). You can, of course, inherit your own COM code domain from this one and override the `_do_equivalent()` function to add semantic equivalence testing for whichever extra COM codes that your application specifically needs. */ using com_code = status_code<_com_code_domain>; //! (Windows only) A specialisation of `status_error` for the COM error code domain. using com_error = status_error<_com_code_domain>; /*! (Windows only) The implementation of the domain for COM error codes and/or `IErrorInfo`. */ class _com_code_domain : public status_code_domain { template <class DomainType> friend class status_code; template <class StatusCode> friend class detail::indirecting_domain; using _base = status_code_domain; //! Construct from a `HRESULT` error code static _base::string_ref _make_string_ref(HRESULT c, IErrorInfo *perrinfo = nullptr) noexcept { _com_error ce(c, perrinfo); #ifdef _UNICODE win32::DWORD wlen = (win32::DWORD) wcslen(ce.ErrorMessage()); size_t allocation = wlen + (wlen >> 1); win32::DWORD bytes; if(wlen == 0) { return _base::string_ref("failed to get message from system"); } for(;;) { auto *p = static_cast<char *>(malloc(allocation)); // NOLINT if(p == nullptr) { return _base::string_ref("failed to get message from system"); } bytes = win32::WideCharToMultiByte(65001 /*CP_UTF8*/, 0, ce.ErrorMessage(), wlen + 1, p, allocation, nullptr, nullptr); if(bytes != 0) { char *end = strchr(p, 0); while(end[-1] == 10 || end[-1] == 13) { --end; } *end = 0; // NOLINT return _base::atomic_refcounted_string_ref(p, end - p); } free(p); // NOLINT if(win32::GetLastError() == 0x7a /*ERROR_INSUFFICIENT_BUFFER*/) { allocation += allocation >> 2; continue; } return _base::string_ref("failed to get message from system"); } #else auto wlen = static_cast<win32::DWORD>(strlen(ce.ErrorMessage())); auto *p = static_cast<char *>(malloc(wlen + 1)); // NOLINT if(p == nullptr) { return _base::string_ref("failed to get message from system"); } memcpy(p, ce.ErrorMessage(), wlen + 1); char *end = strchr(p, 0); while(end[-1] == 10 || end[-1] == 13) { --end; } *end = 0; // NOLINT return _base::atomic_refcounted_string_ref(p, end - p); #endif } public: //! The value type of the COM code, which is a `HRESULT` using value_type = HRESULT; using _base::string_ref; public: //! Default constructor constexpr explicit _com_code_domain(typename _base::unique_id_type id = 0xdc8275428b4effac) noexcept : _base(id) {} _com_code_domain(const _com_code_domain &) = default; _com_code_domain(_com_code_domain &&) = default; _com_code_domain &operator=(const _com_code_domain &) = default; _com_code_domain &operator=(_com_code_domain &&) = default; ~_com_code_domain() = default; //! Constexpr singleton getter. Returns the constexpr com_code_domain variable. static inline constexpr const _com_code_domain &get(); virtual string_ref name() const noexcept override { return string_ref("COM domain"); } // NOLINT protected: virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); return static_cast<const com_code &>(code).value() < 0; // NOLINT } /*! Note semantic equivalence testing is only implemented for `FACILITY_WIN32` and `FACILITY_NT_BIT`. */ virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT { assert(code1.domain() == *this); const auto &c1 = static_cast<const com_code &>(code1); // NOLINT if(code2.domain() == *this) { const auto &c2 = static_cast<const com_code &>(code2); // NOLINT return c1.value() == c2.value(); } if((c1.value() & FACILITY_NT_BIT) != 0) { if(code2.domain() == nt_code_domain) { const auto &c2 = static_cast<const nt_code &>(code2); // NOLINT if(c2.value() == (c1.value() & ~FACILITY_NT_BIT)) { return true; } } else if(code2.domain() == generic_code_domain) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT if(static_cast<int>(c2.value()) == _nt_code_domain::_nt_code_to_errno(c1.value() & ~FACILITY_NT_BIT)) { return true; } } } else if(HRESULT_FACILITY(c1.value()) == FACILITY_WIN32) { if(code2.domain() == win32_code_domain) { const auto &c2 = static_cast<const win32_code &>(code2); // NOLINT if(c2.value() == HRESULT_CODE(c1.value())) { return true; } } else if(code2.domain() == generic_code_domain) { const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT if(static_cast<int>(c2.value()) == _win32_code_domain::_win32_code_to_errno(HRESULT_CODE(c1.value()))) { return true; } } } return false; } virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c1 = static_cast<const com_code &>(code); // NOLINT if(c1.value() == S_OK) { return generic_code(errc::success); } if((c1.value() & FACILITY_NT_BIT) != 0) { return generic_code(static_cast<errc>(_nt_code_domain::_nt_code_to_errno(c1.value() & ~FACILITY_NT_BIT))); } if(HRESULT_FACILITY(c1.value()) == FACILITY_WIN32) { return generic_code(static_cast<errc>(_win32_code_domain::_win32_code_to_errno(HRESULT_CODE(c1.value())))); } return generic_code(errc::unknown); } virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const com_code &>(code); // NOLINT return _make_string_ref(c.value()); } #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT { assert(code.domain() == *this); const auto &c = static_cast<const com_code &>(code); // NOLINT throw status_error<_com_code_domain>(c); } #endif }; //! (Windows only) A constexpr source variable for the COM code domain. Returned by `_com_code_domain::get()`. constexpr _com_code_domain com_code_domain; inline constexpr const _com_code_domain &_com_code_domain::get() { return com_code_domain; } BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/status_code.hpp 0000644 00000061616 15125552774 0014551 0 ustar 00 /* Proposed SG14 status_code (C) 2018 - 2019 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License in the accompanying file Licence.txt or at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Distributed under the Boost Software License, Version 1.0. (See accompanying file Licence.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_CODE_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_CODE_HPP #include "status_code_domain.hpp" #if(__cplusplus >= 201700 || _HAS_CXX17) && !defined(BOOST_OUTCOME_SYSTEM_ERROR2_DISABLE_STD_IN_PLACE) // 0.26 #include <utility> // for in_place BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN using in_place_t = std::in_place_t; using std::in_place; BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #else BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN //! Aliases `std::in_place_t` if on C++ 17 or later, else defined locally. struct in_place_t { explicit in_place_t() = default; }; //! Aliases `std::in_place` if on C++ 17 or later, else defined locally. constexpr in_place_t in_place{}; BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN //! Namespace for user injected mixins namespace mixins { template <class Base, class T> struct mixin : public Base { using Base::Base; }; } // namespace mixins /*! A tag for an erased value type for `status_code<D>`. Available only if `ErasedType` satisfies `traits::is_move_bitcopying<ErasedType>::value`. */ template <class ErasedType, // typename std::enable_if<traits::is_move_bitcopying<ErasedType>::value, bool>::type = true> struct erased { using value_type = ErasedType; }; /*! Specialise this template to quickly wrap a third party enumeration into a custom status code domain. Use like this: ```c++ BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN template <> struct quick_status_code_from_enum<AnotherCode> : quick_status_code_from_enum_defaults<AnotherCode> { // Text name of the enum static constexpr const auto domain_name = "Another Code"; // Unique UUID for the enum. PLEASE use https://www.random.org/cgi-bin/randbyte?nbytes=16&format=h static constexpr const auto domain_uuid = "{be201f65-3962-dd0e-1266-a72e63776a42}"; // Map of each enum value to its text string, and list of semantically equivalent errc's static const std::initializer_list<mapping> &value_mappings() { static const std::initializer_list<mapping<AnotherCode>> v = { // Format is: { enum value, "string representation", { list of errc mappings ... } } {AnotherCode::success1, "Success 1", {errc::success}}, // {AnotherCode::goaway, "Go away", {errc::permission_denied}}, // {AnotherCode::success2, "Success 2", {errc::success}}, // {AnotherCode::error2, "Error 2", {}}, // }; return v; } // Completely optional definition of mixin for the status code synthesised from `Enum`. It can be omitted. template <class Base> struct mixin : Base { using Base::Base; constexpr int custom_method() const { return 42; } }; }; BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END ``` Note that if the `errc` mapping contains `errc::success`, then the enumeration value is considered to be a successful value. Otherwise it is considered to be a failure value. The first value in the `errc` mapping is the one chosen as the `generic_code` conversion. Other values are used during equivalence comparisons. */ template <class Enum> struct quick_status_code_from_enum; namespace detail { template <class T> struct is_status_code { static constexpr bool value = false; }; template <class T> struct is_status_code<status_code<T>> { static constexpr bool value = true; }; template <class T> struct is_erased_status_code { static constexpr bool value = false; }; template <class T> struct is_erased_status_code<status_code<erased<T>>> { static constexpr bool value = true; }; // From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf namespace impl { template <typename... Ts> struct make_void { using type = void; }; template <typename... Ts> using void_t = typename make_void<Ts...>::type; template <class...> struct types { using type = types; }; template <template <class...> class T, class types, class = void> struct test_apply { using type = void; }; template <template <class...> class T, class... Ts> struct test_apply<T, types<Ts...>, void_t<T<Ts...>>> { using type = T<Ts...>; }; } // namespace impl template <template <class...> class T, class... Ts> using test_apply = impl::test_apply<T, impl::types<Ts...>>; template <class T, class... Args> using get_make_status_code_result = decltype(make_status_code(std::declval<T>(), std::declval<Args>()...)); template <class... Args> using safe_get_make_status_code_result = test_apply<get_make_status_code_result, Args...>; } // namespace detail //! Trait returning true if the type is a status code. template <class T> struct is_status_code { static constexpr bool value = detail::is_status_code<typename std::decay<T>::type>::value || detail::is_erased_status_code<typename std::decay<T>::type>::value; }; /*! A type erased lightweight status code reflecting empty, success, or failure. Differs from `status_code<erased<>>` by being always available irrespective of the domain's value type, but cannot be copied, moved, nor destructed. Thus one always passes this around by const lvalue reference. */ template <> class BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI status_code<void> { template <class T> friend class status_code; public: //! The type of the domain. using domain_type = void; //! The type of the status code. using value_type = void; //! The type of a reference to a message string. using string_ref = typename status_code_domain::string_ref; protected: const status_code_domain *_domain{nullptr}; protected: //! No default construction at type erased level status_code() = default; //! No public copying at type erased level status_code(const status_code &) = default; //! No public moving at type erased level status_code(status_code &&) = default; //! No public assignment at type erased level status_code &operator=(const status_code &) = default; //! No public assignment at type erased level status_code &operator=(status_code &&) = default; //! No public destruction at type erased level ~status_code() = default; //! Used to construct a non-empty type erased status code constexpr explicit status_code(const status_code_domain *v) noexcept : _domain(v) { } public: //! Return the status code domain. constexpr const status_code_domain &domain() const noexcept { return *_domain; } //! True if the status code is empty. BOOST_OUTCOME_SYSTEM_ERROR2_NODISCARD constexpr bool empty() const noexcept { return _domain == nullptr; } //! Return a reference to a string textually representing a code. string_ref message() const noexcept { return (_domain != nullptr) ? _domain->_do_message(*this) : string_ref("(empty)"); } //! True if code means success. bool success() const noexcept { return (_domain != nullptr) ? !_domain->_do_failure(*this) : false; } //! True if code means failure. bool failure() const noexcept { return (_domain != nullptr) ? _domain->_do_failure(*this) : false; } /*! True if code is strictly (and potentially non-transitively) semantically equivalent to another code in another domain. Note that usually non-semantic i.e. pure value comparison is used when the other status code has the same domain. As `equivalent()` will try mapping to generic code, this usually captures when two codes have the same semantic meaning in `equivalent()`. */ template <class T> bool strictly_equivalent(const status_code<T> &o) const noexcept { if(_domain && o._domain) { return _domain->_do_equivalent(*this, o); } // If we are both empty, we are equivalent if(!_domain && !o._domain) { return true; // NOLINT } // Otherwise not equivalent return false; } /*! True if code is equivalent, by any means, to another code in another domain (guaranteed transitive). Firstly `strictly_equivalent()` is run in both directions. If neither succeeds, each domain is asked for the equivalent generic code and those are compared. */ template <class T> inline bool equivalent(const status_code<T> &o) const noexcept; #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) //! Throw a code as a C++ exception. BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN void throw_exception() const { _domain->_do_throw_exception(*this); abort(); // suppress buggy GCC warning } #endif }; namespace detail { template <class DomainType> struct get_domain_value_type { using domain_type = DomainType; using value_type = typename domain_type::value_type; }; template <class ErasedType> struct get_domain_value_type<erased<ErasedType>> { using domain_type = status_code_domain; using value_type = ErasedType; }; template <class DomainType> class BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI status_code_storage : public status_code<void> { using _base = status_code<void>; public: //! The type of the domain. using domain_type = typename get_domain_value_type<DomainType>::domain_type; //! The type of the status code. using value_type = typename get_domain_value_type<DomainType>::value_type; //! The type of a reference to a message string. using string_ref = typename domain_type::string_ref; #ifndef NDEBUG static_assert(std::is_move_constructible<value_type>::value || std::is_copy_constructible<value_type>::value, "DomainType::value_type is neither move nor copy constructible!"); static_assert(!std::is_default_constructible<value_type>::value || std::is_nothrow_default_constructible<value_type>::value, "DomainType::value_type is not nothrow default constructible!"); static_assert(!std::is_move_constructible<value_type>::value || std::is_nothrow_move_constructible<value_type>::value, "DomainType::value_type is not nothrow move constructible!"); static_assert(std::is_nothrow_destructible<value_type>::value, "DomainType::value_type is not nothrow destructible!"); #endif // Replace the type erased implementations with type aware implementations for better codegen //! Return the status code domain. constexpr const domain_type &domain() const noexcept { return *static_cast<const domain_type *>(this->_domain); } //! Reset the code to empty. BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 void clear() noexcept { this->_value.~value_type(); this->_domain = nullptr; new(&this->_value) value_type(); } #if __cplusplus >= 201400 || _MSC_VER >= 1910 /* VS2017 */ //! Return a reference to the `value_type`. constexpr value_type &value() & noexcept { return this->_value; } //! Return a reference to the `value_type`. constexpr value_type &&value() && noexcept { return static_cast<value_type &&>(this->_value); } #endif //! Return a reference to the `value_type`. constexpr const value_type &value() const &noexcept { return this->_value; } //! Return a reference to the `value_type`. constexpr const value_type &&value() const &&noexcept { return static_cast<const value_type &&>(this->_value); } protected: status_code_storage() = default; status_code_storage(const status_code_storage &) = default; BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 status_code_storage(status_code_storage &&o) noexcept : _base(static_cast<status_code_storage &&>(o)) , _value(static_cast<status_code_storage &&>(o)._value) { o._domain = nullptr; } status_code_storage &operator=(const status_code_storage &) = default; BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 status_code_storage &operator=(status_code_storage &&o) noexcept { this->~status_code_storage(); new(this) status_code_storage(static_cast<status_code_storage &&>(o)); return *this; } ~status_code_storage() = default; value_type _value{}; struct _value_type_constructor { }; template <class... Args> constexpr status_code_storage(_value_type_constructor /*unused*/, const status_code_domain *v, Args &&... args) : _base(v) , _value(static_cast<Args &&>(args)...) { } }; } // namespace detail /*! A lightweight, typed, status code reflecting empty, success, or failure. This is the main workhorse of the system_error2 library. Its characteristics reflect the value type set by its domain type, so if that value type is move-only or trivial, so is this. An ADL discovered helper function `make_status_code(T, Args...)` is looked up by one of the constructors. If it is found, and it generates a status code compatible with this status code, implicit construction is made available. You may mix in custom member functions and member function overrides by injecting a specialisation of `mixins::mixin<Base, YourDomainType>`. Your mixin must inherit from `Base`. */ template <class DomainType> class BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI status_code : public mixins::mixin<detail::status_code_storage<DomainType>, DomainType> { template <class T> friend class status_code; using _base = mixins::mixin<detail::status_code_storage<DomainType>, DomainType>; public: //! The type of the domain. using domain_type = DomainType; //! The type of the status code. using value_type = typename domain_type::value_type; //! The type of a reference to a message string. using string_ref = typename domain_type::string_ref; protected: using _base::_base; public: //! Default construction to empty status_code() = default; //! Copy constructor status_code(const status_code &) = default; //! Move constructor status_code(status_code &&) = default; // NOLINT //! Copy assignment status_code &operator=(const status_code &) = default; //! Move assignment status_code &operator=(status_code &&) = default; // NOLINT ~status_code() = default; //! Return a copy of the code. BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 status_code clone() const { return *this; } /***** KEEP THESE IN SYNC WITH ERRORED_STATUS_CODE *****/ //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`. template <class T, class... Args, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<T, Args...>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<!std::is_same<typename std::decay<T>::type, status_code>::value // not copy/move of self && !std::is_same<typename std::decay<T>::type, in_place_t>::value // not in_place_t && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code && std::is_constructible<status_code, MakeStatusCodeResult>::value, // ADLed status code is compatible bool>::type = true> constexpr status_code(T &&v, Args &&... args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT : status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...)) { } //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type. template <class Enum, // class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type, // Enumeration has been activated typename std::enable_if<std::is_constructible<status_code, QuickStatusCodeType>::value, // Its status code is compatible bool>::type = true> constexpr status_code(Enum &&v) noexcept(std::is_nothrow_constructible<status_code, QuickStatusCodeType>::value) // NOLINT : status_code(QuickStatusCodeType(static_cast<Enum &&>(v))) { } //! Explicit in-place construction. Disables if `domain_type::get()` is not a valid expression. template <class... Args> constexpr explicit status_code(in_place_t /*unused */, Args &&... args) noexcept(std::is_nothrow_constructible<value_type, Args &&...>::value) : _base(typename _base::_value_type_constructor{}, &domain_type::get(), static_cast<Args &&>(args)...) { } //! Explicit in-place construction from initialiser list. Disables if `domain_type::get()` is not a valid expression. template <class T, class... Args> constexpr explicit status_code(in_place_t /*unused */, std::initializer_list<T> il, Args &&... args) noexcept(std::is_nothrow_constructible<value_type, std::initializer_list<T>, Args &&...>::value) : _base(typename _base::_value_type_constructor{}, &domain_type::get(), il, static_cast<Args &&>(args)...) { } //! Explicit copy construction from a `value_type`. Disables if `domain_type::get()` is not a valid expression. constexpr explicit status_code(const value_type &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value) : _base(typename _base::_value_type_constructor{}, &domain_type::get(), v) { } //! Explicit move construction from a `value_type`. Disables if `domain_type::get()` is not a valid expression. constexpr explicit status_code(value_type &&v) noexcept(std::is_nothrow_move_constructible<value_type>::value) : _base(typename _base::_value_type_constructor{}, &domain_type::get(), static_cast<value_type &&>(v)) { } /*! Explicit construction from an erased status code. Available only if `value_type` is trivially copyable or move bitcopying, and `sizeof(status_code) <= sizeof(status_code<erased<>>)`. Does not check if domains are equal. */ template <class ErasedType, // typename std::enable_if<detail::type_erasure_is_safe<ErasedType, value_type>::value, bool>::type = true> constexpr explicit status_code(const status_code<erased<ErasedType>> &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value) : status_code(detail::erasure_cast<value_type>(v.value())) { #if __cplusplus >= 201400 assert(v.domain() == this->domain()); #endif } //! Return a reference to a string textually representing a code. string_ref message() const noexcept { return this->_domain ? string_ref(this->domain()._do_message(*this)) : string_ref("(empty)"); } }; namespace traits { template <class DomainType> struct is_move_bitcopying<status_code<DomainType>> { static constexpr bool value = is_move_bitcopying<typename DomainType::value_type>::value; }; } // namespace traits /*! Type erased, move-only status_code, unlike `status_code<void>` which cannot be moved nor destroyed. Available only if `erased<>` is available, which is when the domain's type is trivially copyable or is move relocatable, and if the size of the domain's typed error code is less than or equal to this erased error code. Copy construction is disabled, but if you want a copy call `.clone()`. An ADL discovered helper function `make_status_code(T, Args...)` is looked up by one of the constructors. If it is found, and it generates a status code compatible with this status code, implicit construction is made available. */ template <class ErasedType> class BOOST_OUTCOME_SYSTEM_ERROR2_TRIVIAL_ABI status_code<erased<ErasedType>> : public mixins::mixin<detail::status_code_storage<erased<ErasedType>>, erased<ErasedType>> { template <class T> friend class status_code; using _base = mixins::mixin<detail::status_code_storage<erased<ErasedType>>, erased<ErasedType>>; public: //! The type of the domain (void, as it is erased). using domain_type = void; //! The type of the erased status code. using value_type = ErasedType; //! The type of a reference to a message string. using string_ref = typename _base::string_ref; public: //! Default construction to empty status_code() = default; //! Copy constructor status_code(const status_code &) = delete; //! Move constructor status_code(status_code &&) = default; // NOLINT //! Copy assignment status_code &operator=(const status_code &) = delete; //! Move assignment status_code &operator=(status_code &&) = default; // NOLINT ~status_code() { if(nullptr != this->_domain) { this->_domain->_do_erased_destroy(*this, sizeof(*this)); } } //! Return a copy of the erased code by asking the domain to perform the erased copy. status_code clone() const { if(nullptr == this->_domain) { return {}; } status_code x; this->_domain->_do_erased_copy(x, *this, sizeof(*this)); return x; } /***** KEEP THESE IN SYNC WITH ERRORED_STATUS_CODE *****/ //! Implicit copy construction from any other status code if its value type is trivially copyable and it would fit into our storage template <class DomainType, // typename std::enable_if<std::is_trivially_copyable<typename DomainType::value_type>::value // && detail::type_erasure_is_safe<value_type, typename DomainType::value_type>::value, bool>::type = true> constexpr status_code(const status_code<DomainType> &v) noexcept // NOLINT : _base(typename _base::_value_type_constructor{}, &v.domain(), detail::erasure_cast<value_type>(v.value())) { } //! Implicit move construction from any other status code if its value type is trivially copyable or move bitcopying and it would fit into our storage template <class DomainType, // typename std::enable_if<detail::type_erasure_is_safe<value_type, typename DomainType::value_type>::value, bool>::type = true> BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 status_code(status_code<DomainType> &&v) noexcept // NOLINT : _base(typename _base::_value_type_constructor{}, &v.domain(), detail::erasure_cast<value_type>(v.value())) { v._domain = nullptr; } //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`. template <class T, class... Args, // class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<T, Args...>::type, // Safe ADL lookup of make_status_code(), returns void if not found typename std::enable_if<!std::is_same<typename std::decay<T>::type, status_code>::value // not copy/move of self && !std::is_same<typename std::decay<T>::type, value_type>::value // not copy/move of value type && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code && std::is_constructible<status_code, MakeStatusCodeResult>::value, // ADLed status code is compatible bool>::type = true> constexpr status_code(T &&v, Args &&... args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT : status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...)) { } //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type. template <class Enum, // class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type, // Enumeration has been activated typename std::enable_if<std::is_constructible<status_code, QuickStatusCodeType>::value, // Its status code is compatible bool>::type = true> constexpr status_code(Enum &&v) noexcept(std::is_nothrow_constructible<status_code, QuickStatusCodeType>::value) // NOLINT : status_code(QuickStatusCodeType(static_cast<Enum &&>(v))) { } /**** By rights ought to be removed in any formal standard ****/ //! Reset the code to empty. BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 void clear() noexcept { *this = status_code(); } //! Return the erased `value_type` by value. constexpr value_type value() const noexcept { return this->_value; } }; namespace traits { template <class ErasedType> struct is_move_bitcopying<status_code<erased<ErasedType>>> { static constexpr bool value = true; }; } // namespace traits BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/status_error.hpp 0000644 00000007235 15125552774 0014765 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_ERROR_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_ERROR_HPP #include "status_code.hpp" #include <exception> // for std::exception BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN /*! Exception type representing a thrown status_code */ template <class DomainType> class status_error; /*! The erased type edition of status_error. */ template <> class status_error<void> : public std::exception { protected: //! Constructs an instance. Not publicly available. status_error() = default; //! Copy constructor. Not publicly available status_error(const status_error &) = default; //! Move constructor. Not publicly available status_error(status_error &&) = default; //! Copy assignment. Not publicly available status_error &operator=(const status_error &) = default; //! Move assignment. Not publicly available status_error &operator=(status_error &&) = default; //! Destructor. Not publicly available. ~status_error() override = default; public: //! The type of the status domain using domain_type = void; //! The type of the status code using status_code_type = status_code<void>; }; /*! Exception type representing a thrown status_code */ template <class DomainType> class status_error : public status_error<void> { status_code<DomainType> _code; typename DomainType::string_ref _msgref; public: //! The type of the status domain using domain_type = DomainType; //! The type of the status code using status_code_type = status_code<DomainType>; //! Constructs an instance explicit status_error(status_code<DomainType> code) : _code(static_cast<status_code<DomainType> &&>(code)) , _msgref(_code.message()) { } //! Return an explanatory string virtual const char *what() const noexcept override { return _msgref.c_str(); } // NOLINT //! Returns a reference to the code const status_code_type &code() const & { return _code; } //! Returns a reference to the code status_code_type &code() & { return _code; } //! Returns a reference to the code const status_code_type &&code() const && { return _code; } //! Returns a reference to the code status_code_type &&code() && { return _code; } }; BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END #endif experimental/status-code/system_error2.hpp 0000644 00000003053 15125552774 0015042 0 ustar 00 /* Proposed SG14 status_code (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Feb 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_HPP #define BOOST_OUTCOME_SYSTEM_ERROR2_HPP #include "error.hpp" #endif config.hpp 0000644 00000043464 15125552774 0006552 0 ustar 00 /* Configure Boost.Outcome with Boost (C) 2015-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits) File Created: August 2015 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_V2_CONFIG_HPP #define BOOST_OUTCOME_V2_CONFIG_HPP #include "detail/version.hpp" // Pull in detection of __MINGW64_VERSION_MAJOR #if defined(__MINGW32__) && !defined(DOXYGEN_IS_IN_THE_HOUSE) #include <_mingw.h> #endif #include <boost/config.hpp> #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES #error Boost.Outcome needs variadic template support in the compiler #endif #if defined(BOOST_NO_CXX14_CONSTEXPR) && _MSC_FULL_VER < 191100000 #error Boost.Outcome needs constexpr (C++ 14) support in the compiler #endif #ifdef BOOST_NO_CXX14_VARIABLE_TEMPLATES #error Boost.Outcome needs variable template support in the compiler #endif #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 6 #error Due to a bug in nested template variables parsing, Boost.Outcome does not work on GCCs earlier than v6. #endif #ifndef BOOST_OUTCOME_SYMBOL_VISIBLE #define BOOST_OUTCOME_SYMBOL_VISIBLE BOOST_SYMBOL_VISIBLE #endif #ifdef __has_cpp_attribute #define BOOST_OUTCOME_HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr) #else #define BOOST_OUTCOME_HAS_CPP_ATTRIBUTE(attr) (0) #endif // Weird that Boost.Config doesn't define a BOOST_NO_CXX17_NODISCARD #ifndef BOOST_OUTCOME_NODISCARD #if BOOST_OUTCOME_HAS_CPP_ATTRIBUTE(nodiscard) #define BOOST_OUTCOME_NODISCARD [[nodiscard]] #elif defined(__clang__) // deliberately not GCC #define BOOST_OUTCOME_NODISCARD __attribute__((warn_unused_result)) #elif defined(_MSC_VER) // _Must_inspect_result_ expands into this #define BOOST_OUTCOME_NODISCARD \ __declspec("SAL_name" \ "(" \ "\"_Must_inspect_result_\"" \ "," \ "\"\"" \ "," \ "\"2\"" \ ")") __declspec("SAL_begin") __declspec("SAL_post") __declspec("SAL_mustInspect") __declspec("SAL_post") __declspec("SAL_checkReturn") __declspec("SAL_end") #endif #endif #ifndef BOOST_OUTCOME_NODISCARD #define BOOST_OUTCOME_NODISCARD #endif #ifndef BOOST_OUTCOME_THREAD_LOCAL #ifndef BOOST_NO_CXX11_THREAD_LOCAL #define BOOST_OUTCOME_THREAD_LOCAL thread_local #else #if defined(_MSC_VER) #define BOOST_OUTCOME_THREAD_LOCAL __declspec(thread) #elif defined(__GNUC__) #define BOOST_OUTCOME_THREAD_LOCAL __thread #else #error Unknown compiler, cannot set BOOST_OUTCOME_THREAD_LOCAL #endif #endif #endif // Can't use the QuickCppLib preprocessor metaprogrammed Concepts TS support, so ... #ifndef BOOST_OUTCOME_TEMPLATE #define BOOST_OUTCOME_TEMPLATE(...) template <__VA_ARGS__ #endif #ifndef BOOST_OUTCOME_TREQUIRES #define BOOST_OUTCOME_TREQUIRES(...) , __VA_ARGS__ > #endif #ifndef BOOST_OUTCOME_TEXPR #define BOOST_OUTCOME_TEXPR(...) typename = decltype(__VA_ARGS__) #endif #ifndef BOOST_OUTCOME_TPRED #define BOOST_OUTCOME_TPRED(...) typename = std::enable_if_t<__VA_ARGS__> #endif #ifndef BOOST_OUTCOME_REQUIRES #if defined(__cpp_concepts) && (!defined(_MSC_VER) || _MSC_FULL_VER >= 192400000) // VS 2019 16.3 is broken here #define BOOST_OUTCOME_REQUIRES(...) requires(__VA_ARGS__) #else #define BOOST_OUTCOME_REQUIRES(...) #endif #endif #ifndef BOOST_OUTCOME_ENABLE_LEGACY_SUPPORT_FOR #define BOOST_OUTCOME_ENABLE_LEGACY_SUPPORT_FOR 210 // the v2.1 Outcome release #endif namespace boost { #define BOOST_OUTCOME_V2 //! The Boost.Outcome namespace namespace outcome_v2 { } } /*! The namespace of this Boost.Outcome v2. */ #define BOOST_OUTCOME_V2_NAMESPACE boost::outcome_v2 /*! Expands into the appropriate namespace markup to enter the Boost.Outcome v2 namespace. */ #define BOOST_OUTCOME_V2_NAMESPACE_BEGIN \ namespace boost \ { \ namespace outcome_v2 \ { /*! Expands into the appropriate namespace markup to enter the C++ module exported Boost.Outcome v2 namespace. */ #define BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN \ namespace boost \ { \ namespace outcome_v2 \ { /*! \brief Expands into the appropriate namespace markup to exit the Boost.Outcome v2 namespace. \ingroup config */ #define BOOST_OUTCOME_V2_NAMESPACE_END \ } \ } #include <cstdint> // for uint32_t etc #include <initializer_list> #include <iosfwd> // for future serialisation #include <new> // for placement in moves etc #include <type_traits> #ifndef BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE #if defined(_MSC_VER) && _HAS_CXX17 #define BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE 1 // MSVC always has std::in_place_type #elif __cplusplus >= 201700 // libstdc++ before GCC 6 doesn't have it, despite claiming C++ 17 support #ifdef __has_include #if !__has_include(<variant>) #define BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE 0 // must have it if <variant> is present #endif #endif #ifndef BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE #define BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE 1 #endif #else #define BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE 0 #endif #endif #if BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE #include <utility> // for in_place_type_t BOOST_OUTCOME_V2_NAMESPACE_BEGIN template <class T> using in_place_type_t = std::in_place_type_t<T>; using std::in_place_type; BOOST_OUTCOME_V2_NAMESPACE_END #else BOOST_OUTCOME_V2_NAMESPACE_BEGIN //! Aliases `std::in_place_type_t<T>` if on C++ 17 or later, else defined locally. template <class T> struct in_place_type_t { explicit in_place_type_t() = default; }; //! Aliases `std::in_place_type<T>` if on C++ 17 or later, else defined locally. template <class T> constexpr in_place_type_t<T> in_place_type{}; BOOST_OUTCOME_V2_NAMESPACE_END #endif #ifndef BOOST_OUTCOME_TRIVIAL_ABI #if defined(STANDARDESE_IS_IN_THE_HOUSE) || __clang_major__ >= 7 //! Defined to be `[[clang::trivial_abi]]` when on a new enough clang compiler. Usually automatic, can be overriden. #define BOOST_OUTCOME_TRIVIAL_ABI [[clang::trivial_abi]] #else #define BOOST_OUTCOME_TRIVIAL_ABI #endif #endif BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace detail { // Test if type is an in_place_type_t template <class T> struct is_in_place_type_t { static constexpr bool value = false; }; template <class U> struct is_in_place_type_t<in_place_type_t<U>> { static constexpr bool value = true; }; // Replace void with constructible void_type struct empty_type { }; struct void_type { // We always compare true to another instance of me constexpr bool operator==(void_type /*unused*/) const noexcept { return true; } constexpr bool operator!=(void_type /*unused*/) const noexcept { return false; } }; template <class T> using devoid = std::conditional_t<std::is_void<T>::value, void_type, T>; template <class Output, class Input> using rebind_type5 = Output; template <class Output, class Input> using rebind_type4 = std::conditional_t< // std::is_volatile<Input>::value, // std::add_volatile_t<rebind_type5<Output, std::remove_volatile_t<Input>>>, // rebind_type5<Output, Input>>; template <class Output, class Input> using rebind_type3 = std::conditional_t< // std::is_const<Input>::value, // std::add_const_t<rebind_type4<Output, std::remove_const_t<Input>>>, // rebind_type4<Output, Input>>; template <class Output, class Input> using rebind_type2 = std::conditional_t< // std::is_lvalue_reference<Input>::value, // std::add_lvalue_reference_t<rebind_type3<Output, std::remove_reference_t<Input>>>, // rebind_type3<Output, Input>>; template <class Output, class Input> using rebind_type = std::conditional_t< // std::is_rvalue_reference<Input>::value, // std::add_rvalue_reference_t<rebind_type2<Output, std::remove_reference_t<Input>>>, // rebind_type2<Output, Input>>; // static_assert(std::is_same_v<rebind_type<int, volatile const double &&>, volatile const int &&>, ""); /* True if type is the same or constructible. Works around a bug where clang + libstdc++ pukes on std::is_constructible<filesystem::path, void> (this bug is fixed upstream). */ template <class T, class U> struct _is_explicitly_constructible { static constexpr bool value = std::is_constructible<T, U>::value; }; template <class T> struct _is_explicitly_constructible<T, void> { static constexpr bool value = false; }; template <> struct _is_explicitly_constructible<void, void> { static constexpr bool value = false; }; template <class T, class U> static constexpr bool is_explicitly_constructible = _is_explicitly_constructible<T, U>::value; template <class T, class U> struct _is_implicitly_constructible { static constexpr bool value = std::is_convertible<U, T>::value; }; template <class T> struct _is_implicitly_constructible<T, void> { static constexpr bool value = false; }; template <> struct _is_implicitly_constructible<void, void> { static constexpr bool value = false; }; template <class T, class U> static constexpr bool is_implicitly_constructible = _is_implicitly_constructible<T, U>::value; template <class T, class... Args> struct _is_nothrow_constructible { static constexpr bool value = std::is_nothrow_constructible<T, Args...>::value; }; template <class T> struct _is_nothrow_constructible<T, void> { static constexpr bool value = false; }; template <> struct _is_nothrow_constructible<void, void> { static constexpr bool value = false; }; template <class T, class... Args> static constexpr bool is_nothrow_constructible = _is_nothrow_constructible<T, Args...>::value; template <class T, class... Args> struct _is_constructible { static constexpr bool value = std::is_constructible<T, Args...>::value; }; template <class T> struct _is_constructible<T, void> { static constexpr bool value = false; }; template <> struct _is_constructible<void, void> { static constexpr bool value = false; }; template <class T, class... Args> static constexpr bool is_constructible = _is_constructible<T, Args...>::value; #ifndef BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE #if defined(_MSC_VER) && _HAS_CXX17 #define BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 1 // MSVC always has std::is_nothrow_swappable #elif __cplusplus >= 201700 // libstdc++ before GCC 6 doesn't have it, despite claiming C++ 17 support #ifdef __has_include #if !__has_include(<variant>) #define BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 0 // must have it if <variant> is present #endif #endif #ifndef BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE #define BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 1 #endif #else #define BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 0 #endif #endif // True if type is nothrow swappable #if !defined(STANDARDESE_IS_IN_THE_HOUSE) && BOOST_OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE template <class T> using is_nothrow_swappable = std::is_nothrow_swappable<T>; #else template <class T> struct is_nothrow_swappable { static constexpr bool value = std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value; }; #endif } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #ifndef BOOST_OUTCOME_THROW_EXCEPTION #include <boost/throw_exception.hpp> #define BOOST_OUTCOME_THROW_EXCEPTION(expr) BOOST_THROW_EXCEPTION(expr) #endif #ifndef BOOST_OUTCOME_AUTO_TEST_CASE #define BOOST_OUTCOME_AUTO_TEST_CASE(a, b) BOOST_AUTO_TEST_CASE(a) #endif #endif std_result.hpp 0000644 00000007450 15125552774 0007470 0 ustar 00 /* A very simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (8 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_STD_RESULT_HPP #define BOOST_OUTCOME_STD_RESULT_HPP #include "basic_result.hpp" #include "detail/trait_std_error_code.hpp" #include "detail/trait_std_exception.hpp" #include "policy/fail_to_compile_observers.hpp" #include "policy/result_error_code_throw_as_system_error.hpp" #include "policy/result_exception_ptr_rethrow.hpp" #include "policy/throw_bad_result_access.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ namespace policy { /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class EC, class E> using default_policy = std::conditional_t< // std::is_void<EC>::value && std::is_void<E>::value, terminate, // std::conditional_t< // trait::is_error_code_available<EC>::value, error_code_throw_as_system_error<T, EC, E>, // std::conditional_t< // trait::is_exception_ptr_available<EC>::value || trait::is_exception_ptr_available<E>::value, exception_ptr_rethrow<T, EC, E>, // fail_to_compile_observers // >>>; } // namespace policy /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S = std::error_code, class NoValuePolicy = policy::default_policy<R, S, void>> // using std_result = basic_result<R, S, NoValuePolicy>; /*! AWAITING HUGO JSON CONVERSION TOOL type alias template <class R, class S = std::error_code> std_unchecked. Potential doc page: `std_unchecked<T, E = std::error_code>` */ template <class R, class S = std::error_code> using std_unchecked = std_result<R, S, policy::all_narrow>; /*! AWAITING HUGO JSON CONVERSION TOOL type alias template <class R, class S = std::error_code> std_checked. Potential doc page: `std_checked<T, E = std::error_code>` */ template <class R, class S = std::error_code> using std_checked = std_result<R, S, policy::throw_bad_result_access<S, void>>; BOOST_OUTCOME_V2_NAMESPACE_END #endif convert.hpp 0000644 00000016444 15125552774 0006763 0 ustar 00 /* Says how to convert value, error and exception types (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) File Created: Nov 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_CONVERT_HPP #define BOOST_OUTCOME_CONVERT_HPP #include "detail/basic_result_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace concepts { #if defined(__cpp_concepts) #if !defined(_MSC_VER) && !defined(__clang__) && (__GNUC__ < 9 || __cplusplus < 202000L) #define BOOST_OUTCOME_GCC6_CONCEPT_BOOL bool #else #define BOOST_OUTCOME_GCC6_CONCEPT_BOOL #endif namespace detail { template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL SameHelper = std::is_same<T, U>::value; template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL same_as = detail::SameHelper<T, U> &&detail::SameHelper<U, T>; template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL convertible = std::is_convertible<T, U>::value; template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL base_of = std::is_base_of<T, U>::value; } // namespace detail /* The `value_or_none` concept. \requires That `U::value_type` exists and that `std::declval<U>().has_value()` returns a `bool` and `std::declval<U>().value()` exists. */ template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL value_or_none = requires(U a) { { a.has_value() } ->detail::same_as<bool>; {a.value()}; }; /* The `value_or_error` concept. \requires That `U::value_type` and `U::error_type` exist; that `std::declval<U>().has_value()` returns a `bool`, `std::declval<U>().value()` and `std::declval<U>().error()` exists. */ template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL value_or_error = requires(U a) { { a.has_value() } ->detail::same_as<bool>; {a.value()}; {a.error()}; }; #else namespace detail { struct no_match { }; inline no_match match_value_or_none(...); inline no_match match_value_or_error(...); BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<U>().has_value()), BOOST_OUTCOME_TEXPR(std::declval<U>().value())) inline U match_value_or_none(U &&); BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<U>().has_value()), BOOST_OUTCOME_TEXPR(std::declval<U>().value()), BOOST_OUTCOME_TEXPR(std::declval<U>().error())) inline U match_value_or_error(U &&); template <class U> static constexpr bool value_or_none = !std::is_same<no_match, decltype(match_value_or_none(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; template <class U> static constexpr bool value_or_error = !std::is_same<no_match, decltype(match_value_or_error(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; } // namespace detail /* The `value_or_none` concept. \requires That `U::value_type` exists and that `std::declval<U>().has_value()` returns a `bool` and `std::declval<U>().value()` exists. */ template <class U> static constexpr bool value_or_none = detail::value_or_none<U>; /* The `value_or_error` concept. \requires That `U::value_type` and `U::error_type` exist; that `std::declval<U>().has_value()` returns a `bool`, `std::declval<U>().value()` and `std::declval<U>().error()` exists. */ template <class U> static constexpr bool value_or_error = detail::value_or_error<U>; #endif } // namespace concepts namespace convert { #if BOOST_OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220 #if defined(__cpp_concepts) template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL ValueOrNone = concepts::value_or_none<U>; template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL ValueOrError = concepts::value_or_error<U>; #else template <class U> static constexpr bool ValueOrNone = concepts::value_or_none<U>; template <class U> static constexpr bool ValueOrError = concepts::value_or_error<U>; #endif #endif namespace detail { template <class T, class X> struct make_type { template <class U> static constexpr T value(U &&v) { return T{in_place_type<typename T::value_type>, static_cast<U &&>(v).value()}; } template <class U> static constexpr T error(U &&v) { return T{in_place_type<typename T::error_type>, static_cast<U &&>(v).error()}; } static constexpr T error() { return T{in_place_type<typename T::error_type>}; } }; template <class T> struct make_type<T, void> { template <class U> static constexpr T value(U && /*unused*/) { return T{in_place_type<typename T::value_type>}; } template <class U> static constexpr T error(U && /*unused*/) { return T{in_place_type<typename T::error_type>}; } static constexpr T error() { return T{in_place_type<typename T::error_type>}; } }; } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL type definition value_or_error. Potential doc page: NOT FOUND */ template <class T, class U> struct value_or_error { static constexpr bool enable_result_inputs = false; static constexpr bool enable_outcome_inputs = false; BOOST_OUTCOME_TEMPLATE(class X) BOOST_OUTCOME_TREQUIRES( BOOST_OUTCOME_TPRED(std::is_same<U, std::decay_t<X>>::value // &&concepts::value_or_error<U> // && (std::is_void<typename std::decay_t<X>::value_type>::value || BOOST_OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::value_type, typename std::decay_t<X>::value_type>) // &&(std::is_void<typename std::decay_t<X>::error_type>::value || BOOST_OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::error_type, typename std::decay_t<X>::error_type>) )) constexpr T operator()(X &&v) { return v.has_value() ? detail::make_type<T, typename T::value_type>::value(static_cast<X &&>(v)) : detail::make_type<T, typename U::error_type>::error(static_cast<X &&>(v)); } }; } // namespace convert BOOST_OUTCOME_V2_NAMESPACE_END #endif result.hpp 0000644 00000004517 15125552774 0006617 0 ustar 00 /* A very simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (2 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_RESULT_HPP #define BOOST_OUTCOME_RESULT_HPP #include "boost_result.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! In standalone Outcome, this aliases `std_result<>`. In Boost.Outcome, this aliases `boost_result<>`. */ template <class R, class S = boost::system::error_code, class NoValuePolicy = policy::default_policy<R, S, void>> // using result = boost_result<R, S, NoValuePolicy>; /*! In standalone Outcome, this aliases `std_unchecked<>`. In Boost.Outcome, this aliases `boost_checked<>`. */ template <class R, class S = boost::system::error_code> using unchecked = result<R, S, policy::all_narrow>; /*! In standalone Outcome, this aliases `std_checked<>`. In Boost.Outcome, this aliases `boost_checked<>`. */ template <class R, class S = boost::system::error_code> using checked = result<R, S, policy::throw_bad_result_access<S, void>>; BOOST_OUTCOME_V2_NAMESPACE_END #endif success_failure.hpp 0000644 00000021455 15125552774 0010460 0 ustar 00 /* Type sugar for success and failure (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (25 commits) File Created: July 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_SUCCESS_FAILURE_HPP #define BOOST_OUTCOME_SUCCESS_FAILURE_HPP #include "config.hpp" BOOST_OUTCOME_V2_NAMESPACE_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL type definition template <class T> success_type. Potential doc page: `success_type<T>` */ template <class T> struct BOOST_OUTCOME_NODISCARD success_type { using value_type = T; private: value_type _value; public: success_type() = default; success_type(const success_type &) = default; success_type(success_type &&) = default; // NOLINT success_type &operator=(const success_type &) = default; success_type &operator=(success_type &&) = default; // NOLINT ~success_type() = default; BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_same<success_type, std::decay_t<U>>::value)) constexpr explicit success_type(U &&v) : _value(static_cast<U &&>(v)) // NOLINT { } constexpr value_type &value() & { return _value; } constexpr const value_type &value() const & { return _value; } constexpr value_type &&value() && { return static_cast<value_type &&>(_value); } constexpr const value_type &&value() const && { return static_cast<value_type &&>(_value); } }; template <> struct BOOST_OUTCOME_NODISCARD success_type<void> { using value_type = void; }; /*! Returns type sugar for implicitly constructing a `basic_result<T>` with a successful state, default constructing `T` if necessary. */ inline constexpr success_type<void> success() noexcept { return success_type<void>{}; } /*! Returns type sugar for implicitly constructing a `basic_result<T>` with a successful state. \effects Copies or moves the successful state supplied into the returned type sugar. */ template <class T> inline constexpr success_type<std::decay_t<T>> success(T &&v) { return success_type<std::decay_t<T>>{static_cast<T &&>(v)}; } /*! AWAITING HUGO JSON CONVERSION TOOL type definition template <class EC, class E = void> failure_type. Potential doc page: `failure_type<EC, EP = void>` */ template <class EC, class E = void> struct BOOST_OUTCOME_NODISCARD failure_type { using error_type = EC; using exception_type = E; private: bool _have_error{}, _have_exception{}; error_type _error; exception_type _exception; struct error_init_tag { }; struct exception_init_tag { }; public: failure_type() = default; failure_type(const failure_type &) = default; failure_type(failure_type &&) = default; // NOLINT failure_type &operator=(const failure_type &) = default; failure_type &operator=(failure_type &&) = default; // NOLINT ~failure_type() = default; template <class U, class V> constexpr explicit failure_type(U &&u, V &&v) : _have_error(true) , _have_exception(true) , _error(static_cast<U &&>(u)) , _exception(static_cast<V &&>(v)) { } template <class U> constexpr explicit failure_type(in_place_type_t<error_type> /*unused*/, U &&u, error_init_tag /*unused*/ = error_init_tag()) : _have_error(true) , _error(static_cast<U &&>(u)) , _exception() { } template <class U> constexpr explicit failure_type(in_place_type_t<exception_type> /*unused*/, U &&u, exception_init_tag /*unused*/ = exception_init_tag()) : _have_exception(true) , _error() , _exception(static_cast<U &&>(u)) { } constexpr bool has_error() const { return _have_error; } constexpr bool has_exception() const { return _have_exception; } constexpr error_type &error() & { return _error; } constexpr const error_type &error() const & { return _error; } constexpr error_type &&error() && { return static_cast<error_type &&>(_error); } constexpr const error_type &&error() const && { return static_cast<error_type &&>(_error); } constexpr exception_type &exception() & { return _exception; } constexpr const exception_type &exception() const & { return _exception; } constexpr exception_type &&exception() && { return static_cast<exception_type &&>(_exception); } constexpr const exception_type &&exception() const && { return static_cast<exception_type &&>(_exception); } }; template <class EC> struct BOOST_OUTCOME_NODISCARD failure_type<EC, void> { using error_type = EC; using exception_type = void; private: error_type _error; public: failure_type() = default; failure_type(const failure_type &) = default; failure_type(failure_type &&) = default; // NOLINT failure_type &operator=(const failure_type &) = default; failure_type &operator=(failure_type &&) = default; // NOLINT ~failure_type() = default; BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_same<failure_type, std::decay_t<U>>::value)) constexpr explicit failure_type(U &&u) : _error(static_cast<U &&>(u)) // NOLINT { } constexpr error_type &error() & { return _error; } constexpr const error_type &error() const & { return _error; } constexpr error_type &&error() && { return static_cast<error_type &&>(_error); } constexpr const error_type &&error() const && { return static_cast<error_type &&>(_error); } }; template <class E> struct BOOST_OUTCOME_NODISCARD failure_type<void, E> { using error_type = void; using exception_type = E; private: exception_type _exception; public: failure_type() = default; failure_type(const failure_type &) = default; failure_type(failure_type &&) = default; // NOLINT failure_type &operator=(const failure_type &) = default; failure_type &operator=(failure_type &&) = default; // NOLINT ~failure_type() = default; BOOST_OUTCOME_TEMPLATE(class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_same<failure_type, std::decay_t<V>>::value)) constexpr explicit failure_type(V &&v) : _exception(static_cast<V &&>(v)) // NOLINT { } constexpr exception_type &exception() & { return _exception; } constexpr const exception_type &exception() const & { return _exception; } constexpr exception_type &&exception() && { return static_cast<exception_type &&>(_exception); } constexpr const exception_type &&exception() const && { return static_cast<exception_type &&>(_exception); } }; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class EC> inline constexpr failure_type<std::decay_t<EC>> failure(EC &&v) { return failure_type<std::decay_t<EC>>{static_cast<EC &&>(v)}; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class EC, class E> inline constexpr failure_type<std::decay_t<EC>, std::decay_t<E>> failure(EC &&v, E &&w) { return failure_type<std::decay_t<EC>, std::decay_t<E>>{static_cast<EC &&>(v), static_cast<E &&>(w)}; } namespace detail { template <class T> struct is_success_type { static constexpr bool value = false; }; template <class T> struct is_success_type<success_type<T>> { static constexpr bool value = true; }; template <class T> struct is_failure_type { static constexpr bool value = false; }; template <class EC, class E> struct is_failure_type<failure_type<EC, E>> { static constexpr bool value = true; }; } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> static constexpr bool is_success_type = detail::is_success_type<std::decay_t<T>>::value; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> static constexpr bool is_failure_type = detail::is_failure_type<std::decay_t<T>>::value; BOOST_OUTCOME_V2_NAMESPACE_END #endif coroutine_support.hpp 0000644 00000010366 15125552774 0011103 0 ustar 00 /* Tells C++ coroutines about Outcome's result (C) 2019-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) File Created: Oct 2019 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_COROUTINE_SUPPORT_HPP #define BOOST_OUTCOME_COROUTINE_SUPPORT_HPP #include "config.hpp" #define BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN \ BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace awaitables \ { // #define BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN \ BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace awaitables \ { // #define BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END \ } \ BOOST_OUTCOME_V2_NAMESPACE_END #ifndef BOOST_NO_EXCEPTIONS #include "utils.hpp" BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace awaitables { namespace detail { inline bool error_is_set(std::error_code ec) noexcept { return !!ec; } inline std::error_code error_from_exception(std::exception_ptr &&ep, std::error_code not_matched) noexcept { return BOOST_OUTCOME_V2_NAMESPACE::error_from_exception(static_cast<std::exception_ptr &&>(ep), not_matched); } } // namespace detail } // namespace awaitables BOOST_OUTCOME_V2_NAMESPACE_END #endif #include "detail/coroutine_support.ipp" #undef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN #undef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN #undef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END #endif boost_result.hpp 0000644 00000014120 15125552774 0010014 0 ustar 00 /* A very simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (10 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BOOST_RESULT_HPP #define BOOST_OUTCOME_BOOST_RESULT_HPP #include "config.hpp" #include "boost/system/system_error.hpp" #include "boost/exception_ptr.hpp" #include "boost/version.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ namespace policy { namespace detail { /* Pass through `make_error_code` function for `boost::system::error_code`. */ inline boost::system::error_code make_error_code(boost::system::error_code v) { return v; } /* Pass through `make_exception_ptr` function for `boost::exception_ptr`. */ inline boost::exception_ptr make_exception_ptr(boost::exception_ptr v) { return v; } } // namespace detail } // namespace policy BOOST_OUTCOME_V2_NAMESPACE_END #include "std_result.hpp" // ADL injection of outcome_throw_as_system_error_with_payload namespace boost { namespace system { inline void outcome_throw_as_system_error_with_payload(const error_code &error) { BOOST_OUTCOME_THROW_EXCEPTION(system_error(error)); } namespace errc { BOOST_OUTCOME_TEMPLATE(class Error) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(is_error_code_enum<std::decay_t<Error>>::value || is_error_condition_enum<std::decay_t<Error>>::value)) inline void outcome_throw_as_system_error_with_payload(Error &&error) { BOOST_OUTCOME_THROW_EXCEPTION(system_error(make_error_code(error))); } } // namespace errc } // namespace system } // namespace boost BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { // Customise _set_error_is_errno template <class State> constexpr inline void _set_error_is_errno(State &state, const boost::system::error_code &error) { if(error.category() == boost::system::generic_category() #ifndef _WIN32 || error.category() == boost::system::system_category() #endif ) { state._status.set_have_error_is_errno(true); } } template <class State> constexpr inline void _set_error_is_errno(State &state, const boost::system::error_condition &error) { if(error.category() == boost::system::generic_category() #ifndef _WIN32 || error.category() == boost::system::system_category() #endif ) { state._status.set_have_error_is_errno(true); } } template <class State> constexpr inline void _set_error_is_errno(State &state, const boost::system::errc::errc_t & /*unused*/) { state._status.set_have_error_is_errno(true); } } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ namespace trait { namespace detail { // Shortcut these for lower build impact template <> struct _is_error_code_available<boost::system::error_code> { static constexpr bool value = true; using type = boost::system::error_code; }; template <> struct _is_exception_ptr_available<boost::exception_ptr> { static constexpr bool value = true; using type = boost::exception_ptr; }; } // namespace detail // boost::system::error_code is an error type template <> struct is_error_type<boost::system::error_code> { static constexpr bool value = true; }; // boost::system::error_code::errc_t is an error type template <> struct is_error_type<boost::system::errc::errc_t> { static constexpr bool value = true; }; // boost::exception_ptr is an error types template <> struct is_error_type<boost::exception_ptr> { static constexpr bool value = true; }; // For boost::system::error_code, boost::system::is_error_condition_enum<> is the trait we want. template <class Enum> struct is_error_type_enum<boost::system::error_code, Enum> { static constexpr bool value = boost::system::is_error_condition_enum<Enum>::value; }; } // namespace trait /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S = boost::system::error_code, class NoValuePolicy = policy::default_policy<R, S, void>> // using boost_result = basic_result<R, S, NoValuePolicy>; /*! AWAITING HUGO JSON CONVERSION TOOL type alias template <class R, class S = boost::system::error_code> boost_unchecked. Potential doc page: `boost_unchecked<T, E = boost::system::error_code>` */ template <class R, class S = boost::system::error_code> using boost_unchecked = boost_result<R, S, policy::all_narrow>; /*! AWAITING HUGO JSON CONVERSION TOOL type alias template <class R, class S = boost::system::error_code> boost_checked. Potential doc page: `boost_checked<T, E = boost::system::error_code>` */ template <class R, class S = boost::system::error_code> using boost_checked = boost_result<R, S, policy::throw_bad_result_access<S, void>>; BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/value_storage.hpp 0000644 00000121716 15125552774 0011404 0 ustar 00 /* Essentially an internal optional implementation :) (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (24 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_VALUE_STORAGE_HPP #define BOOST_OUTCOME_VALUE_STORAGE_HPP #include "../config.hpp" #include <cassert> BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace detail { template <class T, bool nothrow> struct strong_swap_impl { constexpr strong_swap_impl(bool &allgood, T &a, T &b) { allgood = true; using std::swap; swap(a, b); } }; #ifndef BOOST_NO_EXCEPTIONS template <class T> struct strong_swap_impl<T, false> { strong_swap_impl(bool &allgood, T &a, T &b) { allgood = true; T v(static_cast<T &&>(a)); try { a = static_cast<T &&>(b); } catch(...) { // Try to put back a try { a = static_cast<T &&>(v); // fall through as all good } catch(...) { // failed to completely restore allgood = false; // throw away second exception } throw; // rethrow original exception } // b has been moved to a, try to move v to b try { b = static_cast<T &&>(v); } catch(...) { // Try to restore a to b, and v to a try { b = static_cast<T &&>(a); a = static_cast<T &&>(v); // fall through as all good } catch(...) { // failed to completely restore allgood = false; // throw away second exception } throw; // rethrow original exception } } }; #endif } // namespace detail /*! */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(std::is_move_constructible<T>::value &&std::is_move_assignable<T>::value)) constexpr inline void strong_swap(bool &allgood, T &a, T &b) noexcept(detail::is_nothrow_swappable<T>::value) { detail::strong_swap_impl<T, detail::is_nothrow_swappable<T>::value>(allgood, a, b); } namespace detail { template <class T> constexpr #ifdef _MSC_VER __declspec(noreturn) #elif defined(__GNUC__) || defined(__clang__) __attribute__((noreturn)) #endif void make_ub(T && /*unused*/) { assert(false); // NOLINT #if defined(__GNUC__) || defined(__clang__) __builtin_unreachable(); #elif defined(_MSC_VER) __assume(0); #endif } /* Outcome v1 used a C bitfield whose values were tracked by compiler optimisers nicely, but that produces ICEs when used in constexpr. Outcome v2.0-v2.1 used a 32 bit integer and manually set and cleared bits. Unfortunately only GCC's optimiser tracks bit values during constant folding, and only per byte, and even then unreliably. https://wg21.link/P1886 "Error speed benchmarking" showed just how poorly clang and MSVC fails to optimise outcome-using code, if you manually set bits. Outcome v2.2 therefore uses an enum with fixed values, and constexpr manipulation functions to change the value to one of the enum's values. This is stupid to look at in source code, but it make clang's optimiser do the right thing, so it's worth it. */ #define BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS 0 enum class status : uint16_t { // WARNING: These bits are not tracked by abi-dumper, but changing them will break ABI! none = 0, have_value = (1U << 0U), have_error = (1U << 1U), have_exception = (2U << 1U), have_error_exception = (3U << 1U), // failed to complete a strong swap have_lost_consistency = (1U << 3U), have_value_lost_consistency = (1U << 0U) | (1U << 3U), have_error_lost_consistency = (1U << 1U) | (1U << 3U), have_exception_lost_consistency = (2U << 1U) | (1U << 3U), have_error_exception_lost_consistency = (3U << 1U) | (1U << 3U), // can errno be set from this error? have_error_is_errno = (1U << 4U), have_error_error_is_errno = (1U << 1U) | (1U << 4U), have_error_exception_error_is_errno = (3U << 1U) | (1U << 4U), have_error_lost_consistency_error_is_errno = (1U << 1U) | (1U << 3U) | (1U << 4U), have_error_exception_lost_consistency_error_is_errno = (3U << 1U) | (1U << 3U) | (1U << 4U), // value has been moved from have_moved_from = (1U << 5U) }; struct status_bitfield_type { status status_value{status::none}; uint16_t spare_storage_value{0}; // hooks::spare_storage() constexpr status_bitfield_type() = default; constexpr status_bitfield_type(status v) noexcept : status_value(v) { } // NOLINT constexpr status_bitfield_type(status v, uint16_t s) noexcept : status_value(v) , spare_storage_value(s) { } constexpr status_bitfield_type(const status_bitfield_type &) = default; constexpr status_bitfield_type(status_bitfield_type &&) = default; constexpr status_bitfield_type &operator=(const status_bitfield_type &) = default; constexpr status_bitfield_type &operator=(status_bitfield_type &&) = default; //~status_bitfield_type() = default; // Do NOT uncomment this, it breaks older clangs! constexpr bool have_value() const noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS return (status_value == status::have_value) // || (status_value == status::have_value_lost_consistency) // ; #else return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0; #endif } constexpr bool have_error() const noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS return (status_value == status::have_error) // || (status_value == status::have_error_exception) // || (status_value == status::have_error_lost_consistency) // || (status_value == status::have_error_exception_lost_consistency) // || (status_value == status::have_error_error_is_errno) // || (status_value == status::have_error_exception_error_is_errno) // || (status_value == status::have_error_lost_consistency_error_is_errno) // || (status_value == status::have_error_exception_lost_consistency_error_is_errno) // ; #else return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0; #endif } constexpr bool have_exception() const noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS return (status_value == status::have_exception) // || (status_value == status::have_error_exception) // || (status_value == status::have_exception_lost_consistency) // || (status_value == status::have_error_exception_lost_consistency) // || (status_value == status::have_error_exception_error_is_errno) // || (status_value == status::have_error_exception_lost_consistency_error_is_errno) // ; #else return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0; #endif } constexpr bool have_lost_consistency() const noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS return (status_value == status::have_value_lost_consistency) // || (status_value == status::have_error_lost_consistency) // || (status_value == status::have_exception_lost_consistency) // || (status_value == status::have_error_lost_consistency_error_is_errno) // || (status_value == status::have_error_exception_lost_consistency_error_is_errno) // ; #else return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_lost_consistency)) != 0; #endif } constexpr bool have_error_is_errno() const noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS return (status_value == status::have_error_error_is_errno) // || (status_value == status::have_error_exception_error_is_errno) // || (status_value == status::have_error_lost_consistency_error_is_errno) // || (status_value == status::have_error_exception_lost_consistency_error_is_errno) // ; #else return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error_is_errno)) != 0; #endif } constexpr bool have_moved_from() const noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS #error Fixme #else return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0; #endif } constexpr status_bitfield_type &set_have_value(bool v) noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS switch(status_value) { case status::none: if(v) { status_value = status::have_value; } break; case status::have_value: if(!v) { status_value = status::none; } break; case status::have_error: if(v) { make_ub(*this); } break; case status::have_exception: if(v) { make_ub(*this); } break; case status::have_error_exception: if(v) { make_ub(*this); } break; case status::have_value_lost_consistency: if(!v) { status_value = status::none; } break; case status::have_error_lost_consistency: if(v) { make_ub(*this); } break; case status::have_exception_lost_consistency: if(v) { make_ub(*this); } break; case status::have_error_exception_lost_consistency: if(v) { make_ub(*this); } break; case status::have_error_error_is_errno: if(v) { make_ub(*this); } break; case status::have_error_exception_error_is_errno: if(v) { make_ub(*this); } break; case status::have_error_lost_consistency_error_is_errno: if(v) { make_ub(*this); } break; case status::have_error_exception_lost_consistency_error_is_errno: if(v) { make_ub(*this); } break; } #else status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_value)) : (static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_value))); #endif return *this; } constexpr status_bitfield_type &set_have_error(bool v) noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS switch(status_value) { case status::none: if(v) { status_value = status::have_error; } break; case status::have_value: if(v) { make_ub(*this); } break; case status::have_error: if(!v) { status_value = status::none; } break; case status::have_exception: if(v) { status_value = status::have_error_exception; } break; case status::have_error_exception: if(!v) { status_value = status::have_exception; } break; case status::have_value_lost_consistency: if(v) { make_ub(*this); } break; case status::have_error_lost_consistency: if(!v) { status_value = status::none; } break; case status::have_exception_lost_consistency: if(v) { status_value = status::have_error_exception_lost_consistency; } break; case status::have_error_exception_lost_consistency: if(!v) { status_value = status::have_exception_lost_consistency; } break; case status::have_error_error_is_errno: if(!v) { status_value = status::none; } break; case status::have_error_exception_error_is_errno: if(!v) { status_value = status::have_exception; } break; case status::have_error_lost_consistency_error_is_errno: if(!v) { status_value = status::none; } break; case status::have_error_exception_lost_consistency_error_is_errno: if(!v) { status_value = status::have_exception_lost_consistency; } break; } #else status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_error)) : (static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_error))); #endif return *this; } constexpr status_bitfield_type &set_have_exception(bool v) noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS switch(status_value) { case status::none: if(v) { status_value = status::have_exception; } break; case status::have_value: if(v) { make_ub(*this); } break; case status::have_error: if(v) { status_value = status::have_error_exception; } break; case status::have_exception: if(!v) { status_value = status::none; } break; case status::have_error_exception: if(!v) { status_value = status::have_error; } break; case status::have_value_lost_consistency: if(v) { make_ub(*this); } break; case status::have_error_lost_consistency: if(v) { status_value = status::have_error_exception_lost_consistency; } break; case status::have_exception_lost_consistency: if(!v) { status_value = status::none; } break; case status::have_error_exception_lost_consistency: if(!v) { status_value = status::have_error_lost_consistency; } break; case status::have_error_error_is_errno: if(v) { status_value = status::have_error_exception_error_is_errno; } break; case status::have_error_exception_error_is_errno: if(!v) { status_value = status::have_error_error_is_errno; } break; case status::have_error_lost_consistency_error_is_errno: if(v) { status_value = status::have_error_exception_lost_consistency_error_is_errno; } break; case status::have_error_exception_lost_consistency_error_is_errno: if(!v) { status_value = status::have_error_lost_consistency_error_is_errno; } break; } #else status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_exception)) : (static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_exception))); #endif return *this; } constexpr status_bitfield_type &set_have_error_is_errno(bool v) noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS switch(status_value) { case status::none: make_ub(*this); break; case status::have_value: make_ub(*this); break; case status::have_error: if(v) { status_value = status::have_error_error_is_errno; } break; case status::have_exception: make_ub(*this); break; case status::have_error_exception: if(v) { status_value = status::have_error_exception_error_is_errno; } break; case status::have_value_lost_consistency: make_ub(*this); break; case status::have_error_lost_consistency: if(v) { status_value = status::have_error_lost_consistency_error_is_errno; } break; case status::have_exception_lost_consistency: make_ub(*this); break; case status::have_error_exception_lost_consistency: if(v) { status_value = status::have_error_exception_lost_consistency_error_is_errno; } break; case status::have_error_error_is_errno: if(!v) { status_value = status::have_error; } break; case status::have_error_exception_error_is_errno: if(!v) { status_value = status::have_error_exception; } break; case status::have_error_lost_consistency_error_is_errno: if(!v) { status_value = status::have_error_lost_consistency; } break; case status::have_error_exception_lost_consistency_error_is_errno: if(!v) { status_value = status::have_error_exception_lost_consistency; } break; } #else status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_error_is_errno)) : (static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_error_is_errno))); #endif return *this; } constexpr status_bitfield_type &set_have_lost_consistency(bool v) noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS switch(status_value) { case status::none: if(v) { make_ub(*this); } break; case status::have_value: if(v) { status_value = status::have_value_lost_consistency; } break; case status::have_error: if(v) { status_value = status::have_error_lost_consistency; } break; case status::have_exception: if(v) { status_value = status::have_exception_lost_consistency; } break; case status::have_error_exception: if(v) { status_value = status::have_error_exception_lost_consistency; } break; case status::have_value_lost_consistency: if(!v) { status_value = status::have_value; } break; case status::have_error_lost_consistency: if(!v) { status_value = status::have_error; } break; case status::have_exception_lost_consistency: if(!v) { status_value = status::have_exception; } break; case status::have_error_exception_lost_consistency: if(!v) { status_value = status::have_error_exception; } break; case status::have_error_error_is_errno: if(v) { status_value = status::have_error_lost_consistency_error_is_errno; } break; case status::have_error_exception_error_is_errno: if(v) { status_value = status::have_error_exception_lost_consistency_error_is_errno; } break; case status::have_error_lost_consistency_error_is_errno: if(!v) { status_value = status::have_error_exception_error_is_errno; } break; case status::have_error_exception_lost_consistency_error_is_errno: if(!v) { status_value = status::have_error_exception_error_is_errno; } break; } #else status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_lost_consistency)) : (static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_lost_consistency))); #endif return *this; } constexpr status_bitfield_type &set_have_moved_from(bool v) noexcept { #if BOOST_OUTCOME_USE_CONSTEXPR_ENUM_STATUS #error Fixme #else status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_moved_from)) : (static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_moved_from))); #endif return *this; } }; #if !defined(NDEBUG) // Check is trivial in all ways except default constructibility static_assert(sizeof(status_bitfield_type) == 4, "status_bitfield_type is not sized 4 bytes!"); static_assert(std::is_trivially_copyable<status_bitfield_type>::value, "status_bitfield_type is not trivially copyable!"); static_assert(std::is_trivially_assignable<status_bitfield_type, status_bitfield_type>::value, "status_bitfield_type is not trivially assignable!"); static_assert(std::is_trivially_destructible<status_bitfield_type>::value, "status_bitfield_type is not trivially destructible!"); static_assert(std::is_trivially_copy_constructible<status_bitfield_type>::value, "status_bitfield_type is not trivially copy constructible!"); static_assert(std::is_trivially_move_constructible<status_bitfield_type>::value, "status_bitfield_type is not trivially move constructible!"); static_assert(std::is_trivially_copy_assignable<status_bitfield_type>::value, "status_bitfield_type is not trivially copy assignable!"); static_assert(std::is_trivially_move_assignable<status_bitfield_type>::value, "status_bitfield_type is not trivially move assignable!"); // Also check is standard layout static_assert(std::is_standard_layout<status_bitfield_type>::value, "status_bitfield_type is not a standard layout type!"); #endif // Used if T is trivial template <class T> struct value_storage_trivial { using value_type = T; union { empty_type _empty; devoid<T> _value; }; status_bitfield_type _status; constexpr value_storage_trivial() noexcept : _empty{} { } // Special from-void catchall constructor, always constructs default T irrespective of whether void is valued or not (can do no better if T cannot be // copied) struct disable_void_catchall { }; using void_value_storage_trivial = std::conditional_t<std::is_void<T>::value, disable_void_catchall, value_storage_trivial<void>>; explicit constexpr value_storage_trivial(const void_value_storage_trivial &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) : _value() , _status(o._status) { } value_storage_trivial(const value_storage_trivial &) = default; // NOLINT value_storage_trivial(value_storage_trivial &&) = default; // NOLINT value_storage_trivial &operator=(const value_storage_trivial &) = default; // NOLINT value_storage_trivial &operator=(value_storage_trivial &&) = default; // NOLINT ~value_storage_trivial() = default; constexpr explicit value_storage_trivial(status_bitfield_type status) : _empty() , _status(status) { } template <class... Args> constexpr explicit value_storage_trivial(in_place_type_t<value_type> /*unused*/, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>) : _value(static_cast<Args &&>(args)...) , _status(status::have_value) { } template <class U, class... Args> constexpr value_storage_trivial(in_place_type_t<value_type> /*unused*/, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>) : _value(il, static_cast<Args &&>(args)...) , _status(status::have_value) { } template <class U> static constexpr bool enable_converting_constructor = !std::is_same<std::decay_t<U>, value_type>::value && detail::is_constructible<value_type, U>; BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(enable_converting_constructor<U>)) constexpr explicit value_storage_trivial(const value_storage_trivial<U> &o) noexcept(detail::is_nothrow_constructible<value_type, U>) : value_storage_trivial(o._status.have_value() ? value_storage_trivial(in_place_type<value_type>, o._value) : value_storage_trivial()) // NOLINT { _status = o._status; } BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(enable_converting_constructor<U>)) constexpr explicit value_storage_trivial(value_storage_trivial<U> &&o) noexcept(detail::is_nothrow_constructible<value_type, U>) : value_storage_trivial(o._status.have_value() ? value_storage_trivial(in_place_type<value_type>, static_cast<U &&>(o._value)) : value_storage_trivial()) // NOLINT { _status = o._status; } constexpr void swap(value_storage_trivial &o) noexcept { // storage is trivial, so just use assignment auto temp = static_cast<value_storage_trivial &&>(*this); *this = static_cast<value_storage_trivial &&>(o); o = static_cast<value_storage_trivial &&>(temp); } }; // Used if T is non-trivial template <class T> struct value_storage_nontrivial { using value_type = T; union { empty_type _empty; value_type _value; }; status_bitfield_type _status; value_storage_nontrivial() noexcept : _empty{} { } value_storage_nontrivial &operator=(const value_storage_nontrivial &) = default; // if reaches here, copy assignment is trivial value_storage_nontrivial &operator=(value_storage_nontrivial &&) = default; // NOLINT if reaches here, move assignment is trivial value_storage_nontrivial(value_storage_nontrivial &&o) noexcept(std::is_nothrow_move_constructible<value_type>::value) // NOLINT : _status(o._status) { if(this->_status.have_value()) { this->_status.set_have_value(false); new(&_value) value_type(static_cast<value_type &&>(o._value)); // NOLINT _status = o._status; } } value_storage_nontrivial(const value_storage_nontrivial &o) noexcept(std::is_nothrow_copy_constructible<value_type>::value) : _status(o._status) { if(this->_status.have_value()) { this->_status.set_have_value(false); new(&_value) value_type(o._value); // NOLINT _status = o._status; } } // Special from-void constructor, constructs default T if void valued explicit value_storage_nontrivial(const value_storage_trivial<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) : _status(o._status) { if(this->_status.have_value()) { this->_status.set_have_value(false); new(&_value) value_type; // NOLINT _status = o._status; } } explicit value_storage_nontrivial(status_bitfield_type status) : _empty() , _status(status) { } template <class... Args> explicit value_storage_nontrivial(in_place_type_t<value_type> /*unused*/, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>) : _value(static_cast<Args &&>(args)...) // NOLINT , _status(status::have_value) { } template <class U, class... Args> value_storage_nontrivial(in_place_type_t<value_type> /*unused*/, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>) : _value(il, static_cast<Args &&>(args)...) , _status(status::have_value) { } template <class U> static constexpr bool enable_converting_constructor = !std::is_same<std::decay_t<U>, value_type>::value && detail::is_constructible<value_type, U>; BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(enable_converting_constructor<U>)) constexpr explicit value_storage_nontrivial(const value_storage_nontrivial<U> &o) noexcept(detail::is_nothrow_constructible<value_type, U>) : value_storage_nontrivial(o._status.have_value() ? value_storage_nontrivial(in_place_type<value_type>, o._value) : value_storage_nontrivial()) { _status = o._status; } BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(enable_converting_constructor<U>)) constexpr explicit value_storage_nontrivial(const value_storage_trivial<U> &o) noexcept(detail::is_nothrow_constructible<value_type, U>) : value_storage_nontrivial(o._status.have_value() ? value_storage_nontrivial(in_place_type<value_type>, o._value) : value_storage_nontrivial()) { _status = o._status; } BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(enable_converting_constructor<U>)) constexpr explicit value_storage_nontrivial(value_storage_nontrivial<U> &&o) noexcept(detail::is_nothrow_constructible<value_type, U>) : value_storage_nontrivial(o._status.have_value() ? value_storage_nontrivial(in_place_type<value_type>, static_cast<U &&>(o._value)) : value_storage_nontrivial()) { _status = o._status; } BOOST_OUTCOME_TEMPLATE(class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(enable_converting_constructor<U>)) constexpr explicit value_storage_nontrivial(value_storage_trivial<U> &&o) noexcept(detail::is_nothrow_constructible<value_type, U>) : value_storage_nontrivial(o._status.have_value() ? value_storage_nontrivial(in_place_type<value_type>, static_cast<U &&>(o._value)) : value_storage_nontrivial()) { _status = o._status; } ~value_storage_nontrivial() noexcept(std::is_nothrow_destructible<T>::value) { if(this->_status.have_value()) { this->_value.~value_type(); // NOLINT this->_status.set_have_value(false); } } constexpr void swap(value_storage_nontrivial &o) noexcept(detail::is_nothrow_swappable<value_type>::value) { using std::swap; if(!_status.have_value() && !o._status.have_value()) { swap(_status, o._status); return; } if(_status.have_value() && o._status.have_value()) { struct _ { status_bitfield_type &a, &b; bool all_good{false}; ~_() { if(!all_good) { // We lost one of the values a.set_have_lost_consistency(true); b.set_have_lost_consistency(true); } } } _{_status, o._status}; strong_swap(_.all_good, _value, o._value); swap(_status, o._status); return; } // One must be empty and the other non-empty, so use move construction if(_status.have_value()) { // Move construct me into other new(&o._value) value_type(static_cast<value_type &&>(_value)); // NOLINT this->_value.~value_type(); // NOLINT swap(_status, o._status); } else { // Move construct other into me new(&_value) value_type(static_cast<value_type &&>(o._value)); // NOLINT o._value.~value_type(); // NOLINT swap(_status, o._status); } } }; template <class Base> struct value_storage_delete_copy_constructor : Base // NOLINT { using Base::Base; using value_type = typename Base::value_type; value_storage_delete_copy_constructor() = default; value_storage_delete_copy_constructor(const value_storage_delete_copy_constructor &) = delete; value_storage_delete_copy_constructor(value_storage_delete_copy_constructor &&) = default; // NOLINT }; template <class Base> struct value_storage_delete_copy_assignment : Base // NOLINT { using Base::Base; using value_type = typename Base::value_type; value_storage_delete_copy_assignment() = default; value_storage_delete_copy_assignment(const value_storage_delete_copy_assignment &) = default; value_storage_delete_copy_assignment(value_storage_delete_copy_assignment &&) = default; // NOLINT value_storage_delete_copy_assignment &operator=(const value_storage_delete_copy_assignment &o) = delete; value_storage_delete_copy_assignment &operator=(value_storage_delete_copy_assignment &&o) = default; // NOLINT }; template <class Base> struct value_storage_delete_move_assignment : Base // NOLINT { using Base::Base; using value_type = typename Base::value_type; value_storage_delete_move_assignment() = default; value_storage_delete_move_assignment(const value_storage_delete_move_assignment &) = default; value_storage_delete_move_assignment(value_storage_delete_move_assignment &&) = default; // NOLINT value_storage_delete_move_assignment &operator=(const value_storage_delete_move_assignment &o) = default; value_storage_delete_move_assignment &operator=(value_storage_delete_move_assignment &&o) = delete; }; template <class Base> struct value_storage_delete_move_constructor : Base // NOLINT { using Base::Base; using value_type = typename Base::value_type; value_storage_delete_move_constructor() = default; value_storage_delete_move_constructor(const value_storage_delete_move_constructor &) = default; value_storage_delete_move_constructor(value_storage_delete_move_constructor &&) = delete; }; template <class Base> struct value_storage_nontrivial_move_assignment : Base // NOLINT { using Base::Base; using value_type = typename Base::value_type; value_storage_nontrivial_move_assignment() = default; value_storage_nontrivial_move_assignment(const value_storage_nontrivial_move_assignment &) = default; value_storage_nontrivial_move_assignment(value_storage_nontrivial_move_assignment &&) = default; // NOLINT value_storage_nontrivial_move_assignment &operator=(const value_storage_nontrivial_move_assignment &o) = default; value_storage_nontrivial_move_assignment & operator=(value_storage_nontrivial_move_assignment &&o) noexcept(std::is_nothrow_move_assignable<value_type>::value) // NOLINT { if(this->_status.have_value() && o._status.have_value()) { this->_value = static_cast<value_type &&>(o._value); // NOLINT } else if(this->_status.have_value() && !o._status.have_value()) { this->_value.~value_type(); // NOLINT } else if(!this->_status.have_value() && o._status.have_value()) { new(&this->_value) value_type(static_cast<value_type &&>(o._value)); // NOLINT } this->_status = o._status; return *this; } }; template <class Base> struct value_storage_nontrivial_copy_assignment : Base // NOLINT { using Base::Base; using value_type = typename Base::value_type; value_storage_nontrivial_copy_assignment() = default; value_storage_nontrivial_copy_assignment(const value_storage_nontrivial_copy_assignment &) = default; value_storage_nontrivial_copy_assignment(value_storage_nontrivial_copy_assignment &&) = default; // NOLINT value_storage_nontrivial_copy_assignment &operator=(value_storage_nontrivial_copy_assignment &&o) = default; // NOLINT value_storage_nontrivial_copy_assignment & operator=(const value_storage_nontrivial_copy_assignment &o) noexcept(std::is_nothrow_copy_assignable<value_type>::value) { if(this->_status.have_value() && o._status.have_value()) { this->_value = o._value; // NOLINT } else if(this->_status.have_value() && !o._status.have_value()) { this->_value.~value_type(); // NOLINT } else if(!this->_status.have_value() && o._status.have_value()) { new(&this->_value) value_type(o._value); // NOLINT } this->_status = o._status; return *this; } }; // We don't actually need all of std::is_trivial<>, std::is_trivially_copyable<> is sufficient template <class T> using value_storage_select_trivality = std::conditional_t<std::is_trivially_copyable<devoid<T>>::value, value_storage_trivial<T>, value_storage_nontrivial<T>>; template <class T> using value_storage_select_move_constructor = std::conditional_t<std::is_move_constructible<devoid<T>>::value, value_storage_select_trivality<T>, value_storage_delete_move_constructor<value_storage_select_trivality<T>>>; template <class T> using value_storage_select_copy_constructor = std::conditional_t<std::is_copy_constructible<devoid<T>>::value, value_storage_select_move_constructor<T>, value_storage_delete_copy_constructor<value_storage_select_move_constructor<T>>>; template <class T> using value_storage_select_move_assignment = std::conditional_t< std::is_trivially_move_assignable<devoid<T>>::value, value_storage_select_copy_constructor<T>, std::conditional_t<std::is_move_assignable<devoid<T>>::value, value_storage_nontrivial_move_assignment<value_storage_select_copy_constructor<T>>, value_storage_delete_copy_assignment<value_storage_select_copy_constructor<T>>>>; template <class T> using value_storage_select_copy_assignment = std::conditional_t< std::is_trivially_copy_assignable<devoid<T>>::value, value_storage_select_move_assignment<T>, std::conditional_t<std::is_copy_assignable<devoid<T>>::value, value_storage_nontrivial_copy_assignment<value_storage_select_move_assignment<T>>, value_storage_delete_copy_assignment<value_storage_select_move_assignment<T>>>>; template <class T> using value_storage_select_impl = value_storage_select_copy_assignment<T>; #ifndef NDEBUG // Check is trivial in all ways except default constructibility // static_assert(std::is_trivial<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivial!"); // static_assert(std::is_trivially_default_constructible<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially default // constructible!"); static_assert(std::is_trivially_copyable<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially copyable!"); static_assert(std::is_trivially_assignable<value_storage_select_impl<int>, value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially assignable!"); static_assert(std::is_trivially_destructible<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially destructible!"); static_assert(std::is_trivially_copy_constructible<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially copy constructible!"); static_assert(std::is_trivially_move_constructible<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially move constructible!"); static_assert(std::is_trivially_copy_assignable<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially copy assignable!"); static_assert(std::is_trivially_move_assignable<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not trivially move assignable!"); // Also check is standard layout static_assert(std::is_standard_layout<value_storage_select_impl<int>>::value, "value_storage_select_impl<int> is not a standard layout type!"); #endif } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/trait_std_exception.hpp 0000644 00000006271 15125552774 0012615 0 ustar 00 /* Traits for Outcome (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (3 commits) File Created: March 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_TRAIT_STD_EXCEPTION_HPP #define BOOST_OUTCOME_TRAIT_STD_EXCEPTION_HPP #include "../config.hpp" #include <exception> BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace policy { namespace detail { /* Pass through `make_exception_ptr` function for `std::exception_ptr`. */ inline std::exception_ptr make_exception_ptr(std::exception_ptr v) { return v; } // Try ADL, if not use fall backs above template <class T> constexpr inline decltype(auto) exception_ptr(T &&v) { return make_exception_ptr(std::forward<T>(v)); } } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> constexpr inline decltype(auto) exception_ptr(T &&v) { return detail::exception_ptr(std::forward<T>(v)); } namespace detail { template <bool has_error_payload> struct _rethrow_exception { template <class Exception> explicit _rethrow_exception(Exception && /*unused*/) // NOLINT { } }; template <> struct _rethrow_exception<true> { template <class Exception> explicit _rethrow_exception(Exception &&excpt) // NOLINT { // ADL rethrow_exception(policy::exception_ptr(std::forward<Exception>(excpt))); } }; } // namespace detail } // namespace policy namespace trait { namespace detail { // Shortcut this for lower build impact template <> struct _is_exception_ptr_available<std::exception_ptr> { static constexpr bool value = true; using type = std::exception_ptr; }; } // namespace detail // std::exception_ptr is an error type template <> struct is_error_type<std::exception_ptr> { static constexpr bool value = true; }; } // namespace trait BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/trait_std_error_code.hpp 0000644 00000011320 15125552774 0012731 0 ustar 00 /* Traits for Outcome (C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) File Created: March 2018 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_TRAIT_STD_ERROR_CODE_HPP #define BOOST_OUTCOME_TRAIT_STD_ERROR_CODE_HPP #include "../config.hpp" #include <system_error> BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace detail { // Customise _set_error_is_errno template <class State> constexpr inline void _set_error_is_errno(State &state, const std::error_code &error) { if(error.category() == std::generic_category() #ifndef _WIN32 || error.category() == std::system_category() #endif ) { state._status.set_have_error_is_errno(true); } } template <class State> constexpr inline void _set_error_is_errno(State &state, const std::error_condition &error) { if(error.category() == std::generic_category() #ifndef _WIN32 || error.category() == std::system_category() #endif ) { state._status.set_have_error_is_errno(true); } } template <class State> constexpr inline void _set_error_is_errno(State &state, const std::errc & /*unused*/) { state._status.set_have_error_is_errno(true); } } // namespace detail namespace policy { namespace detail { /* Pass through `make_error_code` function for `std::error_code`. */ inline std::error_code make_error_code(std::error_code v) { return v; } // Try ADL, if not use fall backs above template <class T> constexpr inline decltype(auto) error_code(T &&v) { return make_error_code(std::forward<T>(v)); } struct std_enum_overload_tag { }; } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> constexpr inline decltype(auto) error_code(T &&v) { return detail::error_code(std::forward<T>(v)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ // inline void outcome_throw_as_system_error_with_payload(...) = delete; // To use the error_code_throw_as_system_error policy with a custom Error type, you must define a outcome_throw_as_system_error_with_payload() free function to say how to handle the payload inline void outcome_throw_as_system_error_with_payload(const std::error_code &error) { BOOST_OUTCOME_THROW_EXCEPTION(std::system_error(error)); } // NOLINT BOOST_OUTCOME_TEMPLATE(class Error) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(std::is_error_code_enum<std::decay_t<Error>>::value || std::is_error_condition_enum<std::decay_t<Error>>::value)) inline void outcome_throw_as_system_error_with_payload(Error &&error, detail::std_enum_overload_tag /*unused*/ = detail::std_enum_overload_tag()) { BOOST_OUTCOME_THROW_EXCEPTION(std::system_error(make_error_code(error))); } // NOLINT } // namespace policy namespace trait { namespace detail { template <> struct _is_error_code_available<std::error_code> { // Shortcut this for lower build impact static constexpr bool value = true; using type = std::error_code; }; } // namespace detail // std::error_code is an error type template <> struct is_error_type<std::error_code> { static constexpr bool value = true; }; // For std::error_code, std::is_error_condition_enum<> is the trait we want. template <class Enum> struct is_error_type_enum<std::error_code, Enum> { static constexpr bool value = std::is_error_condition_enum<Enum>::value; }; } // namespace trait BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/basic_outcome_exception_observers.hpp 0000644 00000005536 15125552774 0015531 0 ustar 00 /* Exception observers for outcome type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (3 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_HPP #define BOOST_OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_HPP #include "basic_result_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { template <class Base, class R, class S, class P, class NoValuePolicy> class basic_outcome_exception_observers : public Base { public: using exception_type = P; using Base::Base; constexpr inline exception_type &assume_exception() & noexcept; constexpr inline const exception_type &assume_exception() const &noexcept; constexpr inline exception_type &&assume_exception() && noexcept; constexpr inline const exception_type &&assume_exception() const &&noexcept; constexpr inline exception_type &exception() &; constexpr inline const exception_type &exception() const &; constexpr inline exception_type &&exception() &&; constexpr inline const exception_type &&exception() const &&; }; // Exception observers not present template <class Base, class R, class S, class NoValuePolicy> class basic_outcome_exception_observers<Base, R, S, void, NoValuePolicy> : public Base { public: using Base::Base; constexpr void assume_exception() const noexcept { NoValuePolicy::narrow_exception_check(this); } constexpr void exception() const { NoValuePolicy::wide_exception_check(this); } }; } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/basic_result_value_observers.hpp 0000644 00000007653 15125552774 0014514 0 ustar 00 /* Value observers for a very simple basic_result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (2 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_RESULT_VALUE_OBSERVERS_HPP #define BOOST_OUTCOME_RESULT_VALUE_OBSERVERS_HPP #include "basic_result_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { template <class Base, class R, class NoValuePolicy> class basic_result_value_observers : public Base { public: using value_type = R; using Base::Base; constexpr value_type &assume_value() & noexcept { NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &>(*this)); return this->_state._value; // NOLINT } constexpr const value_type &assume_value() const &noexcept { NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &>(*this)); return this->_state._value; // NOLINT } constexpr value_type &&assume_value() && noexcept { NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &&>(*this)); return static_cast<value_type &&>(this->_state._value); // NOLINT } constexpr const value_type &&assume_value() const &&noexcept { NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &&>(*this)); return static_cast<const value_type &&>(this->_state._value); // NOLINT } constexpr value_type &value() & { NoValuePolicy::wide_value_check(static_cast<basic_result_value_observers &>(*this)); return this->_state._value; // NOLINT } constexpr const value_type &value() const & { NoValuePolicy::wide_value_check(static_cast<const basic_result_value_observers &>(*this)); return this->_state._value; // NOLINT } constexpr value_type &&value() && { NoValuePolicy::wide_value_check(static_cast<basic_result_value_observers &&>(*this)); return static_cast<value_type &&>(this->_state._value); // NOLINT } constexpr const value_type &&value() const && { NoValuePolicy::wide_value_check(static_cast<const basic_result_value_observers &&>(*this)); return static_cast<const value_type &&>(this->_state._value); // NOLINT } }; template <class Base, class NoValuePolicy> class basic_result_value_observers<Base, void, NoValuePolicy> : public Base { public: using Base::Base; constexpr void assume_value() const noexcept { NoValuePolicy::narrow_value_check(*this); } constexpr void value() const { NoValuePolicy::wide_value_check(*this); } }; } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/basic_outcome_failure_observers.hpp 0000644 00000007700 15125552774 0015155 0 ustar 00 /* Failure observers for outcome type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_OUTCOME_FAILURE_OBSERVERS_HPP #define BOOST_OUTCOME_BASIC_OUTCOME_FAILURE_OBSERVERS_HPP #include "basic_result_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { namespace adl { struct search_detail_adl { }; // Do NOT use template requirements here! template <class S, typename = decltype(basic_outcome_failure_exception_from_error(std::declval<S>()))> inline auto _delayed_lookup_basic_outcome_failure_exception_from_error(const S &ec, search_detail_adl /*unused*/) { // ADL discovered return basic_outcome_failure_exception_from_error(ec); } } // namespace adl #if defined(_MSC_VER) && _MSC_VER <= 1923 // VS2019 // VS2017 and VS2019 with /permissive- chokes on the correct form due to over eager early instantiation. template <class S, class P> inline void _delayed_lookup_basic_outcome_failure_exception_from_error(...) { static_assert(sizeof(S) == 0, "No specialisation for these error and exception types available!"); } #else template <class S, class P> inline void _delayed_lookup_basic_outcome_failure_exception_from_error(...) = delete; // NOLINT No specialisation for these error and exception types available! #endif template <class exception_type> inline exception_type current_exception_or_fatal(std::exception_ptr e) { std::rethrow_exception(e); } template <> inline std::exception_ptr current_exception_or_fatal<std::exception_ptr>(std::exception_ptr e) { return e; } template <class Base, class R, class S, class P, class NoValuePolicy> class basic_outcome_failure_observers : public Base { public: using exception_type = P; using Base::Base; exception_type failure() const noexcept { #ifndef BOOST_NO_EXCEPTIONS try #endif { if(this->_state._status.have_exception()) { return this->assume_exception(); } if(this->_state._status.have_error()) { return _delayed_lookup_basic_outcome_failure_exception_from_error(this->assume_error(), adl::search_detail_adl()); } return exception_type(); } #ifndef BOOST_NO_EXCEPTIONS catch(...) { // Return the failure if exception_type is std::exception_ptr, // otherwise terminate same as throwing an exception inside noexcept return current_exception_or_fatal<exception_type>(std::current_exception()); } #endif } }; } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/version.hpp 0000644 00000003654 15125552774 0010231 0 ustar 00 /* Sets Outcome version (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (4 commits) Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*! AWAITING HUGO JSON CONVERSION TOOL */ #define BOOST_OUTCOME_VERSION_MAJOR 2 /*! AWAITING HUGO JSON CONVERSION TOOL */ #define BOOST_OUTCOME_VERSION_MINOR 1 /*! AWAITING HUGO JSON CONVERSION TOOL */ #define BOOST_OUTCOME_VERSION_PATCH 0 /*! AWAITING HUGO JSON CONVERSION TOOL */ #define BOOST_OUTCOME_VERSION_REVISION 0 // Revision version for cmake and DLL version stamping /*! AWAITING HUGO JSON CONVERSION TOOL */ #ifndef BOOST_OUTCOME_DISABLE_ABI_PERMUTATION #define BOOST_OUTCOME_UNSTABLE_VERSION #endif detail/revision.hpp 0000644 00000003334 15125552774 0010375 0 ustar 00 /* UPDATED BY SCRIPT (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (225 commits) Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time #define BOOST_OUTCOME_PREVIOUS_COMMIT_REF a853fc09bb9590204a33c62bd3fd32f9b212c69f #define BOOST_OUTCOME_PREVIOUS_COMMIT_DATE "2020-10-09 09:46:07 +00:00" #define BOOST_OUTCOME_PREVIOUS_COMMIT_UNIQUE a853fc09 detail/basic_result_final.hpp 0000644 00000016516 15125552774 0012375 0 ustar 00 /* Finaliser for a very simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_RESULT_FINAL_HPP #define BOOST_OUTCOME_BASIC_RESULT_FINAL_HPP #include "basic_result_error_observers.hpp" #include "basic_result_value_observers.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { template <class R, class EC, class NoValuePolicy> using select_basic_result_impl = basic_result_error_observers<basic_result_value_observers<basic_result_storage<R, EC, NoValuePolicy>, R, NoValuePolicy>, EC, NoValuePolicy>; template <class R, class S, class NoValuePolicy> class basic_result_final #if defined(BOOST_OUTCOME_DOXYGEN_IS_IN_THE_HOUSE) : public basic_result_error_observers<basic_result_value_observers<basic_result_storage<R, S, NoValuePolicy>, R, NoValuePolicy>, S, NoValuePolicy> #else : public select_basic_result_impl<R, S, NoValuePolicy> #endif { using base = select_basic_result_impl<R, S, NoValuePolicy>; public: using base::base; constexpr explicit operator bool() const noexcept { return this->_state._status.have_value(); } constexpr bool has_value() const noexcept { return this->_state._status.have_value(); } constexpr bool has_error() const noexcept { return this->_state._status.have_error(); } constexpr bool has_exception() const noexcept { return this->_state._status.have_exception(); } constexpr bool has_lost_consistency() const noexcept { return this->_state._status.have_lost_consistency(); } constexpr bool has_failure() const noexcept { return this->_state._status.have_error() || this->_state._status.have_exception(); } BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<R>>() == std::declval<detail::devoid<T>>()), // BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<S>>() == std::declval<detail::devoid<U>>())) constexpr bool operator==(const basic_result_final<T, U, V> &o) const noexcept( // noexcept(std::declval<detail::devoid<R>>() == std::declval<detail::devoid<T>>()) && noexcept(std::declval<detail::devoid<S>>() == std::declval<detail::devoid<U>>())) { if(this->_state._status.have_value() && o._state._status.have_value()) { return this->_state._value == o._state._value; // NOLINT } if(this->_state._status.have_error() && o._state._status.have_error()) { return this->_error == o._error; } return false; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<R>() == std::declval<T>())) constexpr bool operator==(const success_type<T> &o) const noexcept( // noexcept(std::declval<R>() == std::declval<T>())) { if(this->_state._status.have_value()) { return this->_state._value == o.value(); } return false; } constexpr bool operator==(const success_type<void> &o) const noexcept { (void) o; return this->_state._status.have_value(); } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<S>() == std::declval<T>())) constexpr bool operator==(const failure_type<T, void> &o) const noexcept( // noexcept(std::declval<S>() == std::declval<T>())) { if(this->_state._status.have_error()) { return this->_error == o.error(); } return false; } BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<R>>() != std::declval<detail::devoid<T>>()), // BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<S>>() != std::declval<detail::devoid<U>>())) constexpr bool operator!=(const basic_result_final<T, U, V> &o) const noexcept( // noexcept(std::declval<detail::devoid<R>>() != std::declval<detail::devoid<T>>()) && noexcept(std::declval<detail::devoid<S>>() != std::declval<detail::devoid<U>>())) { if(this->_state._status.have_value() && o._state._status.have_value()) { return this->_state._value != o._state._value; } if(this->_state._status.have_error() && o._state._status.have_error()) { return this->_error != o._error; } return true; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<R>() != std::declval<T>())) constexpr bool operator!=(const success_type<T> &o) const noexcept( // noexcept(std::declval<R>() != std::declval<T>())) { if(this->_state._status.have_value()) { return this->_state._value != o.value(); } return false; } constexpr bool operator!=(const success_type<void> &o) const noexcept { (void) o; return !this->_state._status.have_value(); } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<S>() != std::declval<T>())) constexpr bool operator!=(const failure_type<T, void> &o) const noexcept( // noexcept(std::declval<S>() != std::declval<T>())) { if(this->_state._status.have_error()) { return this->_error != o.error(); } return true; } }; template <class T, class U, class V, class W> constexpr inline bool operator==(const success_type<W> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b == a; } template <class T, class U, class V, class W> constexpr inline bool operator==(const failure_type<W, void> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b == a; } template <class T, class U, class V, class W> constexpr inline bool operator!=(const success_type<W> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b != a; } template <class T, class U, class V, class W> constexpr inline bool operator!=(const failure_type<W, void> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b != a; } } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/basic_result_storage.hpp 0000644 00000033270 15125552774 0012744 0 ustar 00 /* Storage for a very simple basic_result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_RESULT_STORAGE_HPP #define BOOST_OUTCOME_BASIC_RESULT_STORAGE_HPP #include "../success_failure.hpp" #include "../trait.hpp" #include "value_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { template <class State, class E> constexpr inline void _set_error_is_errno(State & /*unused*/, const E & /*unused*/) {} template <class R, class EC, class NoValuePolicy> class basic_result_storage; } // namespace detail namespace hooks { template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_storage<R, S, NoValuePolicy> *r) noexcept; template <class R, class S, class NoValuePolicy> constexpr inline void set_spare_storage(detail::basic_result_storage<R, S, NoValuePolicy> *r, uint16_t v) noexcept; } // namespace hooks namespace policy { struct base; } // namespace policy namespace detail { template <bool value_throws, bool error_throws> struct basic_result_storage_swap; template <class R, class EC, class NoValuePolicy> // class basic_result_storage { static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result"); static_assert(trait::type_can_be_used_in_basic_result<EC>, "The type S cannot be used in a basic_result"); static_assert(std::is_void<EC>::value || std::is_default_constructible<EC>::value, "The type S must be void or default constructible"); friend struct policy::base; template <class T, class U, class V> // friend class basic_result_storage; template <class T, class U, class V> friend class basic_result_final; template <class T, class U, class V> friend constexpr inline uint16_t hooks::spare_storage(const detail::basic_result_storage<T, U, V> *r) noexcept; // NOLINT template <class T, class U, class V> friend constexpr inline void hooks::set_spare_storage(detail::basic_result_storage<T, U, V> *r, uint16_t v) noexcept; // NOLINT template <bool value_throws, bool error_throws> struct basic_result_storage_swap; struct disable_in_place_value_type { }; struct disable_in_place_error_type { }; protected: using _value_type = std::conditional_t<std::is_same<R, EC>::value, disable_in_place_value_type, R>; using _error_type = std::conditional_t<std::is_same<R, EC>::value, disable_in_place_error_type, EC>; using _state_type = value_storage_select_impl<_value_type>; #ifdef BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE detail::value_storage_trivial<_value_type> _state; #else _state_type _state; #endif devoid<_error_type> _error; public: // Used by iostream support to access state _state_type &_iostreams_state() { return _state; } const _state_type &_iostreams_state() const { return _state; } // Hack to work around MSVC bug in /permissive- _state_type &_msvc_nonpermissive_state() { return _state; } devoid<_error_type> &_msvc_nonpermissive_error() { return _error; } protected: basic_result_storage() = default; basic_result_storage(const basic_result_storage &) = default; // NOLINT basic_result_storage(basic_result_storage &&) = default; // NOLINT basic_result_storage &operator=(const basic_result_storage &) = default; // NOLINT basic_result_storage &operator=(basic_result_storage &&) = default; // NOLINT ~basic_result_storage() = default; template <class... Args> constexpr explicit basic_result_storage(in_place_type_t<_value_type> _, Args &&... args) noexcept(detail::is_nothrow_constructible<_value_type, Args...>) : _state{_, static_cast<Args &&>(args)...} , _error() { } template <class U, class... Args> constexpr basic_result_storage(in_place_type_t<_value_type> _, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<_value_type, std::initializer_list<U>, Args...>) : _state{_, il, static_cast<Args &&>(args)...} , _error() { } template <class... Args> constexpr explicit basic_result_storage(in_place_type_t<_error_type> /*unused*/, Args &&... args) noexcept(detail::is_nothrow_constructible<_error_type, Args...>) : _state{detail::status::have_error} , _error(static_cast<Args &&>(args)...) { _set_error_is_errno(_state, _error); } template <class U, class... Args> constexpr basic_result_storage(in_place_type_t<_error_type> /*unused*/, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<_error_type, std::initializer_list<U>, Args...>) : _state{detail::status::have_error} , _error{il, static_cast<Args &&>(args)...} { _set_error_is_errno(_state, _error); } struct compatible_conversion_tag { }; template <class T, class U, class V> constexpr basic_result_storage(compatible_conversion_tag /*unused*/, const basic_result_storage<T, U, V> &o) noexcept(detail::is_nothrow_constructible<_value_type, T> &&detail::is_nothrow_constructible<_error_type, U>) : _state(o._state) , _error(o._error) { } template <class T, class V> constexpr basic_result_storage(compatible_conversion_tag /*unused*/, const basic_result_storage<T, void, V> &o) noexcept(detail::is_nothrow_constructible<_value_type, T>) : _state(o._state) , _error(_error_type{}) { } template <class T, class U, class V> constexpr basic_result_storage(compatible_conversion_tag /*unused*/, basic_result_storage<T, U, V> &&o) noexcept(detail::is_nothrow_constructible<_value_type, T> &&detail::is_nothrow_constructible<_error_type, U>) : _state(static_cast<decltype(o._state) &&>(o._state)) , _error(static_cast<U &&>(o._error)) { } template <class T, class V> constexpr basic_result_storage(compatible_conversion_tag /*unused*/, basic_result_storage<T, void, V> &&o) noexcept(detail::is_nothrow_constructible<_value_type, T>) : _state(static_cast<decltype(o._state) &&>(o._state)) , _error(_error_type{}) { } struct make_error_code_compatible_conversion_tag { }; template <class T, class U, class V> constexpr basic_result_storage(make_error_code_compatible_conversion_tag /*unused*/, const basic_result_storage<T, U, V> &o) noexcept(detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_error_code(std::declval<U>()))) : _state(o._state) , _error(make_error_code(o._error)) { } template <class T, class U, class V> constexpr basic_result_storage(make_error_code_compatible_conversion_tag /*unused*/, basic_result_storage<T, U, V> &&o) noexcept(detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_error_code(std::declval<U>()))) : _state(static_cast<decltype(o._state) &&>(o._state)) , _error(make_error_code(static_cast<U &&>(o._error))) { } struct make_exception_ptr_compatible_conversion_tag { }; template <class T, class U, class V> constexpr basic_result_storage(make_exception_ptr_compatible_conversion_tag /*unused*/, const basic_result_storage<T, U, V> &o) noexcept(detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_exception_ptr(std::declval<U>()))) : _state(o._state) , _error(make_exception_ptr(o._error)) { } template <class T, class U, class V> constexpr basic_result_storage(make_exception_ptr_compatible_conversion_tag /*unused*/, basic_result_storage<T, U, V> &&o) noexcept(detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_exception_ptr(std::declval<U>()))) : _state(static_cast<decltype(o._state) &&>(o._state)) , _error(make_exception_ptr(static_cast<U &&>(o._error))) { } }; // Neither value nor error type can throw during swap #ifndef BOOST_NO_EXCEPTIONS template <> struct basic_result_storage_swap<false, false> #else template <bool value_throws, bool error_throws> struct basic_result_storage_swap #endif { template <class R, class EC, class NoValuePolicy> constexpr basic_result_storage_swap(basic_result_storage<R, EC, NoValuePolicy> &a, basic_result_storage<R, EC, NoValuePolicy> &b) { using std::swap; a._msvc_nonpermissive_state().swap(b._msvc_nonpermissive_state()); swap(a._msvc_nonpermissive_error(), b._msvc_nonpermissive_error()); } }; #ifndef BOOST_NO_EXCEPTIONS // Swap potentially throwing value first template <> struct basic_result_storage_swap<true, false> { template <class R, class EC, class NoValuePolicy> constexpr basic_result_storage_swap(basic_result_storage<R, EC, NoValuePolicy> &a, basic_result_storage<R, EC, NoValuePolicy> &b) { using std::swap; a._msvc_nonpermissive_state().swap(b._msvc_nonpermissive_state()); swap(a._msvc_nonpermissive_error(), b._msvc_nonpermissive_error()); } }; // Swap potentially throwing error first template <> struct basic_result_storage_swap<false, true> { template <class R, class EC, class NoValuePolicy> constexpr basic_result_storage_swap(basic_result_storage<R, EC, NoValuePolicy> &a, basic_result_storage<R, EC, NoValuePolicy> &b) { struct _ { status_bitfield_type &a, &b; bool all_good{false}; ~_() { if(!all_good) { // We lost one of the values a.set_have_lost_consistency(true); b.set_have_lost_consistency(true); } } } _{a._msvc_nonpermissive_state()._status, b._msvc_nonpermissive_state()._status}; strong_swap(_.all_good, a._msvc_nonpermissive_error(), b._msvc_nonpermissive_error()); a._msvc_nonpermissive_state().swap(b._msvc_nonpermissive_state()); } }; // Both could throw template <> struct basic_result_storage_swap<true, true> { template <class R, class EC, class NoValuePolicy> basic_result_storage_swap(basic_result_storage<R, EC, NoValuePolicy> &a, basic_result_storage<R, EC, NoValuePolicy> &b) { using std::swap; // Swap value and status first, if it throws, status will remain unchanged a._msvc_nonpermissive_state().swap(b._msvc_nonpermissive_state()); bool all_good = false; try { strong_swap(all_good, a._msvc_nonpermissive_error(), b._msvc_nonpermissive_error()); } catch(...) { if(!all_good) { a._msvc_nonpermissive_state()._status.set_have_lost_consistency(true); b._msvc_nonpermissive_state()._status.set_have_lost_consistency(true); } else { // We may still be able to rescue tis // First try to put the value and status back try { a._msvc_nonpermissive_state().swap(b._msvc_nonpermissive_state()); // If that succeeded, continue by rethrowing the exception } catch(...) { all_good = false; } } if(!all_good) { // We are now trapped. The value swapped, the error did not, // trying to restore the value failed. We now have // inconsistent result objects. Best we can do is fix up the // status bits to prevent has_value() == has_error(). auto check = [](basic_result_storage<R, EC, NoValuePolicy> &x) { bool has_value = x._state._status.have_value(); bool has_error = x._state._status.have_error(); bool has_exception = x._state._status.have_exception(); x._state._status.set_have_lost_consistency(true); if(has_value == (has_error || has_exception)) { if(has_value) { // We know the value swapped and is now set, so clear error and exception x._state._status.set_have_error(false).set_have_exception(false); } else { // We know the value swapped and is now unset, so set error x._state._status.set_have_error(true); // TODO: Should I default construct reset _error? It's guaranteed default constructible. } } }; check(a); check(b); } throw; } } }; #endif } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/basic_outcome_exception_observers_impl.hpp 0000644 00000013661 15125552774 0016550 0 ustar 00 /* Exception observers for outcome type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_IMPL_HPP #define BOOST_OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_IMPL_HPP #include "basic_outcome_exception_observers.hpp" #include "../policy/base.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace policy { template <class R, class S, class P, class NoValuePolicy, class Impl> inline constexpr auto &&base::_exception(Impl &&self) noexcept { // Impl will be some internal implementation class which has no knowledge of the _ptr stored // beneath it. So statically cast, preserving rvalue and constness, to the derived class. using Outcome = BOOST_OUTCOME_V2_NAMESPACE::detail::rebind_type<basic_outcome<R, S, P, NoValuePolicy>, decltype(self)>; #if defined(_MSC_VER) && _MSC_VER < 1920 // VS2017 tries a copy construction in the correct implementation despite that Outcome is always a rvalue or lvalue ref! :( basic_outcome<R, S, P, NoValuePolicy> &_self = (basic_outcome<R, S, P, NoValuePolicy> &) (self); // NOLINT #else Outcome _self = static_cast<Outcome>(self); // NOLINT #endif return static_cast<Outcome>(_self)._ptr; } } // namespace policy namespace detail { template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() & noexcept { NoValuePolicy::narrow_exception_check(*this); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() const &noexcept { NoValuePolicy::narrow_exception_check(*this); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() && noexcept { NoValuePolicy::narrow_exception_check(std::move(*this)); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this)); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() const &&noexcept { NoValuePolicy::narrow_exception_check(std::move(*this)); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this)); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() & { NoValuePolicy::wide_exception_check(*this); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() const & { NoValuePolicy::wide_exception_check(*this); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() && { NoValuePolicy::wide_exception_check(std::move(*this)); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this)); } template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() const && { NoValuePolicy::wide_exception_check(std::move(*this)); return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this)); } } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif detail/coroutine_support.ipp 0000644 00000033422 15125552774 0012344 0 ustar 00 /* Tells C++ coroutines about Outcome's result (C) 2019-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) File Created: Oct 2019 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN #error This header must only be included by outcome/coroutine_support.hpp or outcome/experimental/coroutine_support.hpp #endif #ifndef BOOST_OUTCOME_DETAIL_COROUTINE_SUPPORT_HPP #define BOOST_OUTCOME_DETAIL_COROUTINE_SUPPORT_HPP #include <atomic> #include <cassert> #if __cpp_impl_coroutine || (defined(_MSC_VER) && __cpp_coroutines) || (defined(__clang__) && __cpp_coroutines) #ifndef BOOST_OUTCOME_HAVE_NOOP_COROUTINE #if defined(__has_builtin) #if __has_builtin(__builtin_coro_noop) #define BOOST_OUTCOME_HAVE_NOOP_COROUTINE 1 #endif #endif #endif #ifndef BOOST_OUTCOME_HAVE_NOOP_COROUTINE #if _MSC_VER >= 1928 #define BOOST_OUTCOME_HAVE_NOOP_COROUTINE 1 #else #define BOOST_OUTCOME_HAVE_NOOP_COROUTINE 0 #endif #endif #if __has_include(<coroutine>) #include <coroutine> BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace awaitables { template <class Promise = void> using coroutine_handle = std::coroutine_handle<Promise>; template <class... Args> using coroutine_traits = std::coroutine_traits<Args...>; using std::suspend_always; using std::suspend_never; #if BOOST_OUTCOME_HAVE_NOOP_COROUTINE using std::noop_coroutine; #endif } // namespace awaitables BOOST_OUTCOME_V2_NAMESPACE_END #define BOOST_OUTCOME_FOUND_COROUTINE_HEADER 1 #elif __has_include(<experimental/coroutine>) #include <experimental/coroutine> BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace awaitables { template <class Promise = void> using coroutine_handle = std::experimental::coroutine_handle<Promise>; template <class... Args> using coroutine_traits = std::experimental::coroutine_traits<Args...>; using std::experimental::suspend_always; using std::experimental::suspend_never; #if BOOST_OUTCOME_HAVE_NOOP_COROUTINE using std::experimental::noop_coroutine; #endif } // namespace awaitables BOOST_OUTCOME_V2_NAMESPACE_END #define BOOST_OUTCOME_FOUND_COROUTINE_HEADER 1 #endif #endif BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace awaitables { namespace detail { struct error_type_not_found { }; struct exception_type_not_found { }; template <class T> struct type_found { using type = T; }; template <class T, class U = typename T::error_type> constexpr inline type_found<U> extract_error_type(int /*unused*/) { return {}; } template <class T> constexpr inline type_found<error_type_not_found> extract_error_type(...) { return {}; } template <class T, class U = typename T::exception_type> constexpr inline type_found<U> extract_exception_type(int /*unused*/) { return {}; } template <class T> constexpr inline type_found<exception_type_not_found> extract_exception_type(...) { return {}; } BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(BOOST_OUTCOME_V2_NAMESPACE::detail::is_constructible<U, T>)) inline bool try_set_error(T &&e, U *result) { new(result) U(static_cast<T &&>(e)); return true; } template <class T> inline bool try_set_error(T && /*unused*/, ...) { return false; } BOOST_OUTCOME_TEMPLATE(class T, class U) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(BOOST_OUTCOME_V2_NAMESPACE::detail::is_constructible<U, T>)) inline void set_or_rethrow(T &e, U *result) { new(result) U(e); } template <class T> inline void set_or_rethrow(T &e, ...) { rethrow_exception(e); } template <class T> class fake_atomic { T _v; public: constexpr fake_atomic(T v) : _v(v) { } T load(std::memory_order /*unused*/) { return _v; } void store(T v, std::memory_order /*unused*/) { _v = v; } }; #ifdef BOOST_OUTCOME_FOUND_COROUTINE_HEADER template <class Awaitable, bool suspend_initial, bool use_atomic, bool is_void> struct outcome_promise_type { using container_type = typename Awaitable::container_type; using result_set_type = std::conditional_t<use_atomic, std::atomic<bool>, fake_atomic<bool>>; union { BOOST_OUTCOME_V2_NAMESPACE::detail::empty_type _default{}; container_type result; }; result_set_type result_set{false}; coroutine_handle<> continuation; outcome_promise_type() noexcept {} outcome_promise_type(const outcome_promise_type &) = delete; outcome_promise_type(outcome_promise_type &&) = delete; outcome_promise_type &operator=(const outcome_promise_type &) = delete; outcome_promise_type &operator=(outcome_promise_type &&) = delete; ~outcome_promise_type() { if(result_set.load(std::memory_order_acquire)) { result.~container_type(); // could throw } } auto get_return_object() { return Awaitable{*this}; // could throw bad_alloc } void return_value(container_type &&value) { assert(!result_set.load(std::memory_order_acquire)); if(result_set.load(std::memory_order_acquire)) { result.~container_type(); // could throw } new(&result) container_type(static_cast<container_type &&>(value)); // could throw result_set.store(true, std::memory_order_release); } void return_value(const container_type &value) { assert(!result_set.load(std::memory_order_acquire)); if(result_set.load(std::memory_order_acquire)) { result.~container_type(); // could throw } new(&result) container_type(value); // could throw result_set.store(true, std::memory_order_release); } void unhandled_exception() { assert(!result_set.load(std::memory_order_acquire)); if(result_set.load(std::memory_order_acquire)) { result.~container_type(); } #ifndef BOOST_NO_EXCEPTIONS auto e = std::current_exception(); auto ec = detail::error_from_exception(static_cast<decltype(e) &&>(e), {}); // Try to set error code first if(!detail::error_is_set(ec) || !detail::try_set_error(static_cast<decltype(ec) &&>(ec), &result)) { detail::set_or_rethrow(e, &result); // could throw } #else std::terminate(); #endif result_set.store(true, std::memory_order_release); } auto initial_suspend() noexcept { struct awaiter { bool await_ready() noexcept { return !suspend_initial; } void await_resume() noexcept {} void await_suspend(coroutine_handle<> /*unused*/) noexcept {} }; return awaiter{}; } auto final_suspend() noexcept { struct awaiter { bool await_ready() noexcept { return false; } void await_resume() noexcept {} #if BOOST_OUTCOME_HAVE_NOOP_COROUTINE coroutine_handle<> await_suspend(coroutine_handle<outcome_promise_type> self) noexcept { return self.promise().continuation ? self.promise().continuation : noop_coroutine(); } #else void await_suspend(coroutine_handle<outcome_promise_type> self) { if(self.promise().continuation) { return self.promise().continuation.resume(); } } #endif }; return awaiter{}; } }; template <class Awaitable, bool suspend_initial, bool use_atomic> struct outcome_promise_type<Awaitable, suspend_initial, use_atomic, true> { using container_type = void; using result_set_type = std::conditional_t<use_atomic, std::atomic<bool>, fake_atomic<bool>>; result_set_type result_set{false}; coroutine_handle<> continuation; outcome_promise_type() {} outcome_promise_type(const outcome_promise_type &) = delete; outcome_promise_type(outcome_promise_type &&) = delete; outcome_promise_type &operator=(const outcome_promise_type &) = delete; outcome_promise_type &operator=(outcome_promise_type &&) = delete; ~outcome_promise_type() = default; auto get_return_object() { return Awaitable{*this}; // could throw bad_alloc } void return_void() noexcept { assert(!result_set.load(std::memory_order_acquire)); result_set.store(true, std::memory_order_release); } void unhandled_exception() { assert(!result_set.load(std::memory_order_acquire)); std::rethrow_exception(std::current_exception()); // throws } auto initial_suspend() noexcept { struct awaiter { bool await_ready() noexcept { return !suspend_initial; } void await_resume() noexcept {} void await_suspend(coroutine_handle<> /*unused*/) noexcept {} }; return awaiter{}; } auto final_suspend() noexcept { struct awaiter { bool await_ready() noexcept { return false; } void await_resume() noexcept {} #if BOOST_OUTCOME_HAVE_NOOP_COROUTINE coroutine_handle<> await_suspend(coroutine_handle<outcome_promise_type> self) noexcept { return self.promise().continuation ? self.promise().continuation : noop_coroutine(); } #else void await_suspend(coroutine_handle<outcome_promise_type> self) { if(self.promise().continuation) { return self.promise().continuation.resume(); } } #endif }; return awaiter{}; } }; template <class Awaitable, bool suspend_initial, bool use_atomic> constexpr inline auto move_result_from_promise_if_not_void(outcome_promise_type<Awaitable, suspend_initial, use_atomic, false> &p) { return static_cast<typename Awaitable::container_type &&>(p.result); } template <class Awaitable, bool suspend_initial, bool use_atomic> constexpr inline void move_result_from_promise_if_not_void(outcome_promise_type<Awaitable, suspend_initial, use_atomic, true> & /*unused*/) { } template <class Cont, bool suspend_initial, bool use_atomic> struct BOOST_OUTCOME_NODISCARD awaitable { using container_type = Cont; using promise_type = outcome_promise_type<awaitable, suspend_initial, use_atomic, std::is_void<container_type>::value>; coroutine_handle<promise_type> _h; awaitable(awaitable &&o) noexcept : _h(static_cast<coroutine_handle<promise_type> &&>(o._h)) { o._h = nullptr; } awaitable(const awaitable &o) = delete; awaitable &operator=(awaitable &&) = delete; // as per P1056 awaitable &operator=(const awaitable &) = delete; ~awaitable() { if(_h) { _h.destroy(); } } explicit awaitable(promise_type &p) // could throw : _h(coroutine_handle<promise_type>::from_promise(p)) { } bool await_ready() noexcept { return _h.promise().result_set.load(std::memory_order_acquire); } container_type await_resume() { assert(_h.promise().result_set.load(std::memory_order_acquire)); if(!_h.promise().result_set.load(std::memory_order_acquire)) { std::terminate(); } return detail::move_result_from_promise_if_not_void(_h.promise()); } #if BOOST_OUTCOME_HAVE_NOOP_COROUTINE coroutine_handle<> await_suspend(coroutine_handle<> cont) noexcept { _h.promise().continuation = cont; return _h; } #else void await_suspend(coroutine_handle<> cont) { _h.promise().continuation = cont; _h.resume(); } #endif }; #endif } // namespace detail } // namespace awaitables BOOST_OUTCOME_V2_NAMESPACE_END #endif #ifdef BOOST_OUTCOME_FOUND_COROUTINE_HEADER BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> using eager = BOOST_OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, false, false>; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> using atomic_eager = BOOST_OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, false, true>; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> using lazy = BOOST_OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, true, false>; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> using atomic_lazy = BOOST_OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, true, true>; BOOST_OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END #endif detail/basic_result_error_observers.hpp 0000644 00000007447 15125552774 0014532 0 ustar 00 /* Error observers for a very simple basic_result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (2 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_RESULT_ERROR_OBSERVERS_HPP #define BOOST_OUTCOME_BASIC_RESULT_ERROR_OBSERVERS_HPP #include "basic_result_storage.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace detail { template <class Base, class EC, class NoValuePolicy> class basic_result_error_observers : public Base { public: using error_type = EC; using Base::Base; constexpr error_type &assume_error() & noexcept { NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &>(*this)); return this->_error; } constexpr const error_type &assume_error() const &noexcept { NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &>(*this)); return this->_error; } constexpr error_type &&assume_error() && noexcept { NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &&>(*this)); return static_cast<error_type &&>(this->_error); } constexpr const error_type &&assume_error() const &&noexcept { NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &&>(*this)); return static_cast<const error_type &&>(this->_error); } constexpr error_type &error() & { NoValuePolicy::wide_error_check(static_cast<basic_result_error_observers &>(*this)); return this->_error; } constexpr const error_type &error() const & { NoValuePolicy::wide_error_check(static_cast<const basic_result_error_observers &>(*this)); return this->_error; } constexpr error_type &&error() && { NoValuePolicy::wide_error_check(static_cast<basic_result_error_observers &&>(*this)); return static_cast<error_type &&>(this->_error); } constexpr const error_type &&error() const && { NoValuePolicy::wide_error_check(static_cast<const basic_result_error_observers &&>(*this)); return static_cast<const error_type &&>(this->_error); } }; template <class Base, class NoValuePolicy> class basic_result_error_observers<Base, void, NoValuePolicy> : public Base { public: using Base::Base; constexpr void assume_error() const noexcept { NoValuePolicy::narrow_error_check(*this); } constexpr void error() const { NoValuePolicy::wide_error_check(*this); } }; } // namespace detail BOOST_OUTCOME_V2_NAMESPACE_END #endif bad_access.hpp 0000644 00000006045 15125552774 0007346 0 ustar 00 /* Exception types throwable (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (9 commits) File Created: Oct 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BAD_ACCESS_HPP #define BOOST_OUTCOME_BAD_ACCESS_HPP #include "config.hpp" #include <stdexcept> BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL type definition bad_result_access. Potential doc page: `bad_result_access` */ class BOOST_OUTCOME_SYMBOL_VISIBLE bad_result_access : public std::logic_error { public: explicit bad_result_access(const char *what) : std::logic_error(what) { } }; /*! AWAITING HUGO JSON CONVERSION TOOL type definition template <class S> bad_result_access_with. Potential doc page: `bad_result_access_with<EC>` */ template <class S> class BOOST_OUTCOME_SYMBOL_VISIBLE bad_result_access_with : public bad_result_access { S _error; public: explicit bad_result_access_with(S v) : bad_result_access("no value") , _error(std::move(v)) { } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ const S &error() const & { return _error; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ S &error() & { return _error; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ const S &&error() const && { return _error; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ S &&error() && { return _error; } }; /*! AWAITING HUGO JSON CONVERSION TOOL type definition bad_outcome_access. Potential doc page: `bad_outcome_access` */ class BOOST_OUTCOME_SYMBOL_VISIBLE bad_outcome_access : public std::logic_error { public: explicit bad_outcome_access(const char *what) : std::logic_error(what) { } }; BOOST_OUTCOME_V2_NAMESPACE_END #endif outcome.hpp 0000644 00000003677 15125552774 0006762 0 ustar 00 /* A less simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (1 commit) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_OUTCOME_HPP #define BOOST_OUTCOME_OUTCOME_HPP #include "result.hpp" #include "boost_outcome.hpp" BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! In standalone Outcome, this aliases `std_outcome<>`. In Boost.Outcome, this aliases `boost_outcome<>`. */ template <class R, class S = boost::system::error_code, class P = boost::exception_ptr, class NoValuePolicy = policy::default_policy<R, S, P>> // using outcome = boost_outcome<R, S, P, NoValuePolicy>; BOOST_OUTCOME_V2_NAMESPACE_END #endif utils.hpp 0000644 00000011047 15125552774 0006435 0 ustar 00 /* Tries to convert an exception ptr into its equivalent error code (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (11 commits) File Created: July 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_UTILS_HPP #define BOOST_OUTCOME_UTILS_HPP #include "config.hpp" #include <exception> #include <string> #include <system_error> BOOST_OUTCOME_V2_NAMESPACE_BEGIN #ifndef BOOST_NO_EXCEPTIONS /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ inline std::error_code error_from_exception(std::exception_ptr &&ep = std::current_exception(), std::error_code not_matched = std::make_error_code(std::errc::resource_unavailable_try_again)) noexcept { if(!ep) { return {}; } try { std::rethrow_exception(ep); } catch(const std::invalid_argument & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::invalid_argument); } catch(const std::domain_error & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::argument_out_of_domain); } catch(const std::length_error & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::argument_list_too_long); } catch(const std::out_of_range & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::result_out_of_range); } catch(const std::logic_error & /*unused*/) /* base class for this group */ { ep = std::exception_ptr(); return std::make_error_code(std::errc::invalid_argument); } catch(const std::system_error &e) /* also catches ios::failure */ { ep = std::exception_ptr(); return e.code(); } catch(const std::overflow_error & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::value_too_large); } catch(const std::range_error & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::result_out_of_range); } catch(const std::runtime_error & /*unused*/) /* base class for this group */ { ep = std::exception_ptr(); return std::make_error_code(std::errc::resource_unavailable_try_again); } catch(const std::bad_alloc & /*unused*/) { ep = std::exception_ptr(); return std::make_error_code(std::errc::not_enough_memory); } catch(...) { } return not_matched; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ inline void try_throw_std_exception_from_error(std::error_code ec, const std::string &msg = std::string{}) { if(!ec || (ec.category() != std::generic_category() #ifndef _WIN32 && ec.category() != std::system_category() #endif )) { return; } switch(ec.value()) { case EINVAL: throw msg.empty() ? std::invalid_argument("invalid argument") : std::invalid_argument(msg); case EDOM: throw msg.empty() ? std::domain_error("domain error") : std::domain_error(msg); case E2BIG: throw msg.empty() ? std::length_error("length error") : std::length_error(msg); case ERANGE: throw msg.empty() ? std::out_of_range("out of range") : std::out_of_range(msg); case EOVERFLOW: throw msg.empty() ? std::overflow_error("overflow error") : std::overflow_error(msg); case ENOMEM: throw std::bad_alloc(); } } #endif BOOST_OUTCOME_V2_NAMESPACE_END #endif iostream_support.hpp 0000644 00000020664 15125552774 0010721 0 ustar 00 /* iostream specialisations for result and outcome (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (21 commits) File Created: July 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_IOSTREAM_SUPPORT_HPP #define BOOST_OUTCOME_IOSTREAM_SUPPORT_HPP #include "outcome.hpp" #include <iostream> #include <sstream> BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace detail { template <class T> typename std::add_lvalue_reference<T>::type lvalueref() noexcept; template <class T> inline std::ostream &operator<<(std::ostream &s, const value_storage_trivial<T> &v) { s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " "; if(v._status.have_value()) { s << v._value; // NOLINT } return s; } inline std::ostream &operator<<(std::ostream &s, const value_storage_trivial<void> &v) { s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " "; return s; } template <class T> inline std::ostream &operator<<(std::ostream &s, const value_storage_nontrivial<T> &v) { s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " "; if(v._status.have_value()) { s << v._value; // NOLINT } return s; } template <class T> inline std::istream &operator>>(std::istream &s, value_storage_trivial<T> &v) { v = value_storage_trivial<T>(); uint16_t x, y; s >> x >> y; v._status.status_value = static_cast<detail::status>(x); v._status.spare_storage_value = y; if(v._status.have_value()) { new(&v._value) decltype(v._value)(); // NOLINT s >> v._value; // NOLINT } return s; } inline std::istream &operator>>(std::istream &s, value_storage_trivial<devoid<void>> &v) { v = value_storage_trivial<devoid<void>>(); uint16_t x, y; s >> x >> y; v._status.status_value = static_cast<detail::status>(x); v._status.spare_storage_value = y; return s; } template <class T> inline std::istream &operator>>(std::istream &s, value_storage_nontrivial<T> &v) { v = value_storage_nontrivial<T>(); uint16_t x, y; s >> x >> y; v._status.status_value = static_cast<detail::status>(x); v._status.spare_storage_value = y; if(v._status.have_value()) { new(&v._value) decltype(v._value)(); // NOLINT s >> v._value; // NOLINT } return s; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_constructible<std::error_code, T>::value)) inline std::string safe_message(T && /*unused*/) { return {}; } inline std::string safe_message(const std::error_code &ec) { return " (" + ec.message() + ")"; } } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class R, class S, class P) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<R>()), BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<S>())) inline std::istream &operator>>(std::istream &s, basic_result<R, S, P> &v) { s >> v._iostreams_state(); if(v.has_error()) { s >> v.assume_error(); } return s; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class R, class S, class P) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<R>()), BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<S>())) inline std::ostream &operator<<(std::ostream &s, const basic_result<R, S, P> &v) { s << v._iostreams_state(); if(v.has_error()) { s << v.assume_error(); } return s; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class P> inline std::string print(const basic_result<R, S, P> &v) { std::stringstream s; if(v.has_value()) { s << v.value(); } if(v.has_error()) { s << v.error() << detail::safe_message(v.error()); } return s.str(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class S, class P> inline std::string print(const basic_result<void, S, P> &v) { std::stringstream s; if(v.has_value()) { s << "(+void)"; } if(v.has_error()) { s << v.error() << detail::safe_message(v.error()); } return s.str(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class P> inline std::string print(const basic_result<R, void, P> &v) { std::stringstream s; if(v.has_value()) { s << v.value(); } if(v.has_error()) { s << "(-void)"; } return s.str(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class P> inline std::string print(const basic_result<void, void, P> &v) { std::stringstream s; if(v.has_value()) { s << "(+void)"; } if(v.has_error()) { s << "(-void)"; } return s.str(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class R, class S, class P, class N) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<R>()), BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<S>()), BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<P>())) inline std::istream &operator>>(std::istream &s, outcome<R, S, P, N> &v) { s >> v._iostreams_state(); if(v.has_error()) { s >> v.assume_error(); } if(v.has_exception()) { s >> v.assume_exception(); } return s; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class R, class S, class P, class N) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<R>()), BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<S>()), BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<P>())) inline std::ostream &operator<<(std::ostream &s, const outcome<R, S, P, N> &v) { s << v._iostreams_state(); if(v.has_error()) { s << v.assume_error(); } if(v.has_exception()) { s << v.assume_exception(); } return s; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class P, class N> inline std::string print(const outcome<R, S, P, N> &v) { std::stringstream s; int total = static_cast<int>(v.has_value()) + static_cast<int>(v.has_error()) + static_cast<int>(v.has_exception()); if(total > 1) { s << "{ "; } s << print(static_cast<const basic_result<R, S, N> &>(static_cast<const detail::basic_result_final<R, S, N> &>(v))); // NOLINT if(total > 1) { s << ", "; } if(v.has_exception()) { #ifndef BOOST_NO_EXCEPTIONS try { rethrow_exception(v.exception()); } catch(const std::system_error &e) { s << "std::system_error code " << e.code() << ": " << e.what(); } catch(const std::exception &e) { s << "std::exception: " << e.what(); } catch(...) #endif { s << "unknown exception"; } } if(total > 1) { s << " }"; } return s.str(); } BOOST_OUTCOME_V2_NAMESPACE_END #endif std_outcome.hpp 0000644 00000004474 15125552774 0007630 0 ustar 00 /* A less simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_STD_OUTCOME_HPP #define BOOST_OUTCOME_STD_OUTCOME_HPP #include "basic_outcome.hpp" #include "std_result.hpp" #ifndef STD_BASIC_OUTCOME_FAILURE_EXCEPTION_FROM_ERROR #define STD_BASIC_OUTCOME_FAILURE_EXCEPTION_FROM_ERROR namespace std // NOLINT { inline exception_ptr basic_outcome_failure_exception_from_error(const error_code &ec) { return make_exception_ptr(system_error(ec)); } } // namespace std #endif BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S = std::error_code, class P = std::exception_ptr, class NoValuePolicy = policy::default_policy<R, S, P>> // using std_outcome = basic_outcome<R, S, P, NoValuePolicy>; BOOST_OUTCOME_V2_NAMESPACE_END #include "policy/outcome_error_code_throw_as_system_error.hpp" #include "policy/outcome_exception_ptr_rethrow.hpp" #endif try.hpp 0000644 00000046020 15125552774 0006112 0 ustar 00 /* Try operation macros (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (20 commits) File Created: July 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_TRY_HPP #define BOOST_OUTCOME_TRY_HPP #include "success_failure.hpp" BOOST_OUTCOME_V2_NAMESPACE_BEGIN namespace detail { struct has_value_overload { }; struct as_failure_overload { }; struct assume_error_overload { }; struct error_overload { }; struct assume_value_overload { }; struct value_overload { }; //#ifdef __APPLE__ // BOOST_OUTCOME_TEMPLATE(class T, class R = decltype(std::declval<T>()._xcode_workaround_as_failure())) //#else BOOST_OUTCOME_TEMPLATE(class T, class R = decltype(std::declval<T>().as_failure())) //#endif BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(BOOST_OUTCOME_V2_NAMESPACE::is_failure_type<R>)) constexpr inline bool has_as_failure(int /*unused */) { return true; } template <class T> constexpr inline bool has_as_failure(...) { return false; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<T>().assume_error())) constexpr inline bool has_assume_error(int /*unused */) { return true; } template <class T> constexpr inline bool has_assume_error(...) { return false; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<T>().error())) constexpr inline bool has_error(int /*unused */) { return true; } template <class T> constexpr inline bool has_error(...) { return false; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<T>().assume_value())) constexpr inline bool has_assume_value(int /*unused */) { return true; } template <class T> constexpr inline bool has_assume_value(...) { return false; } BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<T>().value())) constexpr inline bool has_value(int /*unused */) { return true; } template <class T> constexpr inline bool has_value(...) { return false; } } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<T>().has_value())) constexpr inline bool try_operation_has_value(T &&v, detail::has_value_overload = {}) { return v.has_value(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::has_as_failure<T>(5))) constexpr inline decltype(auto) try_operation_return_as(T &&v, detail::as_failure_overload = {}) { return static_cast<T &&>(v).as_failure(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!detail::has_as_failure<T>(5) && detail::has_assume_error<T>(5))) constexpr inline decltype(auto) try_operation_return_as(T &&v, detail::assume_error_overload = {}) { return failure(static_cast<T &&>(v).assume_error()); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!detail::has_as_failure<T>(5) && !detail::has_assume_error<T>(5) && detail::has_error<T>(5))) constexpr inline decltype(auto) try_operation_return_as(T &&v, detail::error_overload = {}) { return failure(static_cast<T &&>(v).error()); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::has_assume_value<T>(5))) constexpr inline decltype(auto) try_operation_extract_value(T &&v, detail::assume_value_overload = {}) { return static_cast<T &&>(v).assume_value(); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!detail::has_assume_value<T>(5) && detail::has_value<T>(5))) constexpr inline decltype(auto) try_operation_extract_value(T &&v, detail::value_overload = {}) { return static_cast<T &&>(v).value(); } BOOST_OUTCOME_V2_NAMESPACE_END #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wparentheses" #endif #define BOOST_OUTCOME_TRY_GLUE2(x, y) x##y #define BOOST_OUTCOME_TRY_GLUE(x, y) BOOST_OUTCOME_TRY_GLUE2(x, y) #define BOOST_OUTCOME_TRY_UNIQUE_NAME BOOST_OUTCOME_TRY_GLUE(_outcome_try_unique_name_temporary, __COUNTER__) #define BOOST_OUTCOME_TRY_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, count, ...) count #define BOOST_OUTCOME_TRY_EXPAND_ARGS(args) BOOST_OUTCOME_TRY_RETURN_ARG_COUNT args #define BOOST_OUTCOME_TRY_COUNT_ARGS_MAX8(...) BOOST_OUTCOME_TRY_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)) #define BOOST_OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count #define BOOST_OUTCOME_TRY_OVERLOAD_MACRO1(name, count) BOOST_OUTCOME_TRY_OVERLOAD_MACRO2(name, count) #define BOOST_OUTCOME_TRY_OVERLOAD_MACRO(name, count) BOOST_OUTCOME_TRY_OVERLOAD_MACRO1(name, count) #define BOOST_OUTCOME_TRY_OVERLOAD_GLUE(x, y) x y #define BOOST_OUTCOME_TRY_CALL_OVERLOAD(name, ...) \ BOOST_OUTCOME_TRY_OVERLOAD_GLUE(BOOST_OUTCOME_TRY_OVERLOAD_MACRO(name, BOOST_OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__)) #ifndef BOOST_OUTCOME_TRY_LIKELY #if defined(__clang__) || defined(__GNUC__) #define BOOST_OUTCOME_TRY_LIKELY(expr) (__builtin_expect(!!(expr), true)) #else #define BOOST_OUTCOME_TRY_LIKELY(expr) (expr) #endif #endif // Use if(!expr); else as some compilers assume else clauses are always unlikely #define BOOST_OUTCOME_TRYV2_SUCCESS_LIKELY(unique, ...) \ auto &&unique = (__VA_ARGS__); \ if(BOOST_OUTCOME_TRY_LIKELY(BOOST_OUTCOME_V2_NAMESPACE::try_operation_has_value(unique))) \ ; \ else \ return BOOST_OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_TRY2_SUCCESS_LIKELY(unique, v, ...) \ BOOST_OUTCOME_TRYV2_SUCCESS_LIKELY(unique, __VA_ARGS__); \ v = BOOST_OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_TRYV2_FAILURE_LIKELY(unique, ...) \ auto &&unique = (__VA_ARGS__); \ if(BOOST_OUTCOME_TRY_LIKELY(!BOOST_OUTCOME_V2_NAMESPACE::try_operation_has_value(unique))) \ return BOOST_OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_TRY2_FAILURE_LIKELY(unique, v, ...) \ BOOST_OUTCOME_TRYV2_FAILURE_LIKELY(unique, __VA_ARGS__); \ v = BOOST_OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_CO_TRYV2_SUCCESS_LIKELY(unique, ...) \ auto &&unique = (__VA_ARGS__); \ if(BOOST_OUTCOME_TRY_LIKELY(BOOST_OUTCOME_V2_NAMESPACE::try_operation_has_value(unique))) \ ; \ else \ co_return BOOST_OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_CO_TRY2_SUCCESS_LIKELY(unique, v, ...) \ BOOST_OUTCOME_CO_TRYV2_SUCCESS_LIKELY(unique, __VA_ARGS__); \ v = BOOST_OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_CO_TRYV2_FAILURE_LIKELY(unique, ...) \ auto &&unique = (__VA_ARGS__); \ if(BOOST_OUTCOME_TRY_LIKELY(!BOOST_OUTCOME_V2_NAMESPACE::try_operation_has_value(unique))) \ co_return BOOST_OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique)) #define BOOST_OUTCOME_CO_TRY2_FAILURE_LIKELY(unique, v, ...) \ BOOST_OUTCOME_CO_TRYV2_FAILURE_LIKELY(unique, __VA_ARGS__); \ v = BOOST_OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique)) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRYV(...) BOOST_OUTCOME_TRYV2_SUCCESS_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRYV_FAILURE_LIKELY(...) BOOST_OUTCOME_TRYV2_FAILURE_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRYV(...) BOOST_OUTCOME_CO_TRYV2_SUCCESS_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRYV_FAILURE_LIKELY(...) BOOST_OUTCOME_CO_TRYV2_FAILURE_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, __VA_ARGS__) #if defined(__GNUC__) || defined(__clang__) #define BOOST_OUTCOME_TRYX2(unique, retstmt, ...) \ ({ \ auto &&unique = (__VA_ARGS__); \ if(BOOST_OUTCOME_TRY_LIKELY(BOOST_OUTCOME_V2_NAMESPACE::try_operation_has_value(unique))) \ ; \ else \ retstmt BOOST_OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique)); \ BOOST_OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique)); \ }) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRYX(...) BOOST_OUTCOME_TRYX2(BOOST_OUTCOME_TRY_UNIQUE_NAME, return, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRYX(...) BOOST_OUTCOME_TRYX2(BOOST_OUTCOME_TRY_UNIQUE_NAME, co_return, __VA_ARGS__) #endif /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRYA(v, ...) BOOST_OUTCOME_TRY2_SUCCESS_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, auto &&v, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRYA_FAILURE_LIKELY(v, ...) BOOST_OUTCOME_TRY2_FAILURE_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, auto &&v, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRYA(v, ...) BOOST_OUTCOME_CO_TRY2_SUCCESS_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, auto &&v, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(v, ...) BOOST_OUTCOME_CO_TRY2_FAILURE_LIKELY(BOOST_OUTCOME_TRY_UNIQUE_NAME, auto &&v, __VA_ARGS__) #define BOOST_OUTCOME_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) BOOST_OUTCOME_TRYA(a, b, c, d, e, f, g, h) #define BOOST_OUTCOME_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) BOOST_OUTCOME_TRYA(a, b, c, d, e, f, g) #define BOOST_OUTCOME_TRY_INVOKE_TRY6(a, b, c, d, e, f) BOOST_OUTCOME_TRYA(a, b, c, d, e, f) #define BOOST_OUTCOME_TRY_INVOKE_TRY5(a, b, c, d, e) BOOST_OUTCOME_TRYA(a, b, c, d, e) #define BOOST_OUTCOME_TRY_INVOKE_TRY4(a, b, c, d) BOOST_OUTCOME_TRYA(a, b, c, d) #define BOOST_OUTCOME_TRY_INVOKE_TRY3(a, b, c) BOOST_OUTCOME_TRYA(a, b, c) #define BOOST_OUTCOME_TRY_INVOKE_TRY2(a, b) BOOST_OUTCOME_TRYA(a, b) #define BOOST_OUTCOME_TRY_INVOKE_TRY1(a) BOOST_OUTCOME_TRYV(a) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRY(...) BOOST_OUTCOME_TRY_CALL_OVERLOAD(BOOST_OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY8(a, b, c, d, e, f, g, h) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g, h) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY7(a, b, c, d, e, f, g) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY6(a, b, c, d, e, f) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e, f) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY5(a, b, c, d, e) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY4(a, b, c, d) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY3(a, b, c) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b, c) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY2(a, b) BOOST_OUTCOME_TRYA_FAILURE_LIKELY(a, b) #define BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY1(a) BOOST_OUTCOME_TRYV_FAILURE_LIKELY(a) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRY_FAILURE_LIKELY(...) BOOST_OUTCOME_TRY_CALL_OVERLOAD(BOOST_OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY, __VA_ARGS__) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) BOOST_OUTCOME_CO_TRYA(a, b, c, d, e, f, g, h) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) BOOST_OUTCOME_CO_TRYA(a, b, c, d, e, f, g) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY6(a, b, c, d, e, f) BOOST_OUTCOME_CO_TRYA(a, b, c, d, e, f) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY5(a, b, c, d, e) BOOST_OUTCOME_CO_TRYA(a, b, c, d, e) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY4(a, b, c, d) BOOST_OUTCOME_CO_TRYA(a, b, c, d) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY3(a, b, c) BOOST_OUTCOME_CO_TRYA(a, b, c) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY2(a, b) BOOST_OUTCOME_CO_TRYA(a, b) #define BOOST_OUTCOME_CO_TRY_INVOKE_TRY1(a) BOOST_OUTCOME_CO_TRYV(a) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRY(...) BOOST_OUTCOME_TRY_CALL_OVERLOAD(BOOST_OUTCOME_CO_TRY_INVOKE_TRY, __VA_ARGS__) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_TRY(...) BOOST_OUTCOME_TRY_CALL_OVERLOAD(BOOST_OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY8(a, b, c, d, e, f, g, h) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g, h) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY7(a, b, c, d, e, f, g) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY6(a, b, c, d, e, f) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY5(a, b, c, d, e) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY4(a, b, c, d) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY3(a, b, c) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY2(a, b) BOOST_OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b) #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY1(a) BOOST_OUTCOME_CO_TRYV_FAILURE_LIKELY(a) /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ #define BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY(...) BOOST_OUTCOME_TRY_CALL_OVERLOAD(BOOST_OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY, __VA_ARGS__) #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic pop #endif #endif basic_result.hpp 0000644 00000124474 15125552774 0007765 0 ustar 00 /* A very simple result type (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (14 commits) File Created: June 2017 Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BOOST_OUTCOME_BASIC_RESULT_HPP #define BOOST_OUTCOME_BASIC_RESULT_HPP #include "config.hpp" #include "convert.hpp" #include "detail/basic_result_final.hpp" #include "policy/all_narrow.hpp" #include "policy/terminate.hpp" #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang #endif BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN template <class R, class S, class NoValuePolicy> // class basic_result; namespace detail { // These are reused by basic_outcome to save load on the compiler template <class value_type, class error_type> struct result_predicates { // Predicate for the implicit constructors to be available. Weakened to allow result<int, C enum>. static constexpr bool implicit_constructors_enabled = // !(trait::is_error_type<std::decay_t<value_type>>::value && trait::is_error_type<std::decay_t<error_type>>::value) // both value and error types are not whitelisted error types && ((!detail::is_implicitly_constructible<value_type, error_type> && !detail::is_implicitly_constructible<error_type, value_type>) // if value and error types cannot be constructed into one another || (trait::is_error_type<std::decay_t<error_type>>::value // if error type is a whitelisted error type && !detail::is_implicitly_constructible<error_type, value_type> // AND which cannot be constructed from the value type && std::is_integral<value_type>::value)); // AND the value type is some integral type // Predicate for the value converting constructor to be available. Weakened to allow result<int, C enum>. template <class T> static constexpr bool enable_value_converting_constructor = // implicit_constructors_enabled // && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction && !trait::is_error_type_enum<error_type, std::decay_t<T>>::value // not an enum valid for my error type && ((detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T>) // is unambiguously for value type || (std::is_same<value_type, std::decay_t<T>>::value // OR is my value type exactly && detail::is_implicitly_constructible<value_type, T>) ); // and my value type is constructible from this ref form of T // Predicate for the error converting constructor to be available. Weakened to allow result<int, C enum>. template <class T> static constexpr bool enable_error_converting_constructor = // implicit_constructors_enabled // && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction && !trait::is_error_type_enum<error_type, std::decay_t<T>>::value // not an enum valid for my error type && ((!detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T>) // is unambiguously for error type || (std::is_same<error_type, std::decay_t<T>>::value // OR is my error type exactly && detail::is_implicitly_constructible<error_type, T>) ); // and my error type is constructible from this ref form of T // Predicate for the error condition converting constructor to be available. template <class ErrorCondEnum> static constexpr bool enable_error_condition_converting_constructor = // !is_in_place_type_t<std::decay_t<ErrorCondEnum>>::value // not in place construction && trait::is_error_type_enum<error_type, std::decay_t<ErrorCondEnum>>::value // is an error condition enum /*&& !detail::is_implicitly_constructible<value_type, ErrorCondEnum> && !detail::is_implicitly_constructible<error_type, ErrorCondEnum>*/; // not // constructible // via any other // means // Predicate for the converting constructor from a compatible input to be available. template <class T, class U, class V> static constexpr bool enable_compatible_conversion = // (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // if our value types are constructible &&(std::is_void<U>::value || detail::is_explicitly_constructible<error_type, typename basic_result<T, U, V>::error_type>) // if our error types are constructible ; // Predicate for the converting constructor from a make_error_code() of the input to be available. template <class T, class U, class V> static constexpr bool enable_make_error_code_compatible_conversion = // trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code && !enable_compatible_conversion<T, U, V> // and the normal compatible conversion is not available && (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // and if our value types are constructible &&detail::is_explicitly_constructible<error_type, typename trait::is_error_code_available<U>::type>; // and our error type is constructible from a make_error_code() // Predicate for the converting constructor from a make_exception_ptr() of the input to be available. template <class T, class U, class V> static constexpr bool enable_make_exception_ptr_compatible_conversion = // trait::is_exception_ptr_available<std::decay_t<error_type>>::value // if error type has an exception ptr && !enable_compatible_conversion<T, U, V> // and the normal compatible conversion is not available && (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // and if our value types are constructible &&detail::is_explicitly_constructible<error_type, typename trait::is_exception_ptr_available<U>::type>; // and our error type is constructible from a // make_exception_ptr() // Predicate for the implicit converting inplace constructor from a compatible input to be available. struct disable_inplace_value_error_constructor; template <class... Args> using choose_inplace_value_error_constructor = std::conditional_t< // detail::is_constructible<value_type, Args...> && detail::is_constructible<error_type, Args...>, // disable_inplace_value_error_constructor, // std::conditional_t< // detail::is_constructible<value_type, Args...>, // value_type, // std::conditional_t< // detail::is_constructible<error_type, Args...>, // error_type, // disable_inplace_value_error_constructor>>>; template <class... Args> static constexpr bool enable_inplace_value_error_constructor = implicit_constructors_enabled // && !std::is_same<choose_inplace_value_error_constructor<Args...>, disable_inplace_value_error_constructor>::value; }; template <class T, class U> constexpr inline const U &extract_value_from_success(const success_type<U> &v) { return v.value(); } template <class T, class U> constexpr inline U &&extract_value_from_success(success_type<U> &&v) { return static_cast<success_type<U> &&>(v).value(); } template <class T> constexpr inline T extract_value_from_success(const success_type<void> & /*unused*/) { return T{}; } template <class T, class U, class V> constexpr inline const U &extract_error_from_failure(const failure_type<U, V> &v) { return v.error(); } template <class T, class U, class V> constexpr inline U &&extract_error_from_failure(failure_type<U, V> &&v) { return static_cast<failure_type<U, V> &&>(v).error(); } template <class T, class V> constexpr inline T extract_error_from_failure(const failure_type<void, V> & /*unused*/) { return T{}; } template <class T> struct is_basic_result { static constexpr bool value = false; }; template <class R, class S, class T> struct is_basic_result<basic_result<R, S, T>> { static constexpr bool value = true; }; } // namespace detail /*! AWAITING HUGO JSON CONVERSION TOOL type alias template <class T> is_basic_result. Potential doc page: `is_basic_result<T>` */ template <class T> using is_basic_result = detail::is_basic_result<std::decay_t<T>>; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T> static constexpr bool is_basic_result_v = detail::is_basic_result<std::decay_t<T>>::value; namespace concepts { #if defined(__cpp_concepts) /* The `basic_result` concept. \requires That `U` matches a `basic_result`. */ template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL basic_result = BOOST_OUTCOME_V2_NAMESPACE::is_basic_result<U>::value || (requires(U v) { BOOST_OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>(v); } && // detail::convertible<U, BOOST_OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>> && // detail::base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>, U>); #else namespace detail { inline no_match match_basic_result(...); template <class R, class S, class NVP, class T, // typename = typename T::value_type, // typename = typename T::error_type, // typename = typename T::no_value_policy_type, // typename std::enable_if_t<std::is_convertible<T, BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP>>::value && // std::is_base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP>, T>::value, bool> = true> inline BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP> match_basic_result(BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP> &&, T &&); template <class U> static constexpr bool basic_result = BOOST_OUTCOME_V2_NAMESPACE::is_basic_result<U>::value || !std::is_same<no_match, decltype(match_basic_result(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>(), std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; } // namespace detail /* The `basic_result` concept. \requires That `U` matches a `basic_result`. */ template <class U> static constexpr bool basic_result = detail::basic_result<U>; #endif } // namespace concepts /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ namespace hooks { /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U> constexpr inline void hook_result_construction(T * /*unused*/, U && /*unused*/) noexcept {} /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U> constexpr inline void hook_result_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {} /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U> constexpr inline void hook_result_move_construction(T * /*unused*/, U && /*unused*/) noexcept {} /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class T, class U, class... Args> constexpr inline void hook_result_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept { } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_storage<R, S, NoValuePolicy> *r) noexcept { return r->_state._status.spare_storage_value; } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class NoValuePolicy> constexpr inline void set_spare_storage(detail::basic_result_storage<R, S, NoValuePolicy> *r, uint16_t v) noexcept { r->_state._status.spare_storage_value = v; } } // namespace hooks /*! AWAITING HUGO JSON CONVERSION TOOL type definition template <class R, class S, class NoValuePolicy> basic_result. Potential doc page: `basic_result<T, E, NoValuePolicy>` */ template <class R, class S, class NoValuePolicy> // class BOOST_OUTCOME_NODISCARD basic_result : public detail::basic_result_final<R, S, NoValuePolicy> { static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result"); static_assert(trait::type_can_be_used_in_basic_result<S>, "The type S cannot be used in a basic_result"); static_assert(std::is_void<S>::value || std::is_default_constructible<S>::value, "The type S must be void or default constructible"); using base = detail::basic_result_final<R, S, NoValuePolicy>; struct implicit_constructors_disabled_tag { }; struct value_converting_constructor_tag { }; struct error_converting_constructor_tag { }; struct error_condition_converting_constructor_tag { }; struct explicit_valueornone_converting_constructor_tag { }; struct explicit_valueorerror_converting_constructor_tag { }; struct explicit_compatible_copy_conversion_tag { }; struct explicit_compatible_move_conversion_tag { }; struct explicit_make_error_code_compatible_copy_conversion_tag { }; struct explicit_make_error_code_compatible_move_conversion_tag { }; struct explicit_make_exception_ptr_compatible_copy_conversion_tag { }; struct explicit_make_exception_ptr_compatible_move_conversion_tag { }; public: using value_type = R; using error_type = S; using no_value_policy_type = NoValuePolicy; using value_type_if_enabled = typename base::_value_type; using error_type_if_enabled = typename base::_error_type; template <class T, class U = S, class V = NoValuePolicy> using rebind = basic_result<T, U, V>; protected: // Requirement predicates for result. struct predicate { using base = detail::result_predicates<value_type, error_type>; // Predicate for any constructors to be available at all static constexpr bool constructors_enabled = !std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value; // Predicate for implicit constructors to be available at all static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled; // Predicate for the value converting constructor to be available. template <class T> static constexpr bool enable_value_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<T>, basic_result>::value // not my type && base::template enable_value_converting_constructor<T>; // Predicate for the error converting constructor to be available. template <class T> static constexpr bool enable_error_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<T>, basic_result>::value // not my type && base::template enable_error_converting_constructor<T>; // Predicate for the error condition converting constructor to be available. template <class ErrorCondEnum> static constexpr bool enable_error_condition_converting_constructor = // constructors_enabled // && !std::is_same<std::decay_t<ErrorCondEnum>, basic_result>::value // not my type && base::template enable_error_condition_converting_constructor<ErrorCondEnum>; // Predicate for the converting constructor from a compatible input to be available. template <class T, class U, class V> static constexpr bool enable_compatible_conversion = // constructors_enabled // && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type && base::template enable_compatible_conversion<T, U, V>; // Predicate for the converting constructor from a make_error_code() of the input to be available. template <class T, class U, class V> static constexpr bool enable_make_error_code_compatible_conversion = // constructors_enabled // && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type && base::template enable_make_error_code_compatible_conversion<T, U, V>; // Predicate for the converting constructor from a make_exception_ptr() of the input to be available. template <class T, class U, class V> static constexpr bool enable_make_exception_ptr_compatible_conversion = // constructors_enabled // && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type && base::template enable_make_exception_ptr_compatible_conversion<T, U, V>; // Predicate for the inplace construction of value to be available. template <class... Args> static constexpr bool enable_inplace_value_constructor = // constructors_enabled // && (std::is_void<value_type>::value // || detail::is_constructible<value_type, Args...>); // Predicate for the inplace construction of error to be available. template <class... Args> static constexpr bool enable_inplace_error_constructor = // constructors_enabled // && (std::is_void<error_type>::value // || detail::is_constructible<error_type, Args...>); // Predicate for the implicit converting inplace constructor to be available. template <class... Args> static constexpr bool enable_inplace_value_error_constructor = // constructors_enabled // &&base::template enable_inplace_value_error_constructor<Args...>; template <class... Args> using choose_inplace_value_error_constructor = typename base::template choose_inplace_value_error_constructor<Args...>; }; public: /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ basic_result() = delete; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ basic_result(basic_result && /*unused*/) = default; // NOLINT /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ basic_result(const basic_result & /*unused*/) = default; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ basic_result &operator=(basic_result && /*unused*/) = default; // NOLINT /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ basic_result &operator=(const basic_result & /*unused*/) = default; ~basic_result() = default; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class Arg, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!predicate::constructors_enabled && (sizeof...(Args) >= 0))) basic_result(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_result<T, T> is NOT SUPPORTED, see docs! /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled // && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T>) ))) basic_result(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) = delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs! /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>)) constexpr basic_result(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept( detail::is_nothrow_constructible<value_type, T>) // NOLINT : base{in_place_type<typename base::value_type>, static_cast<T &&>(t)} { using namespace hooks; hook_result_construction(this, static_cast<T &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>)) constexpr basic_result(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept( detail::is_nothrow_constructible<error_type, T>) // NOLINT : base{in_place_type<typename base::error_type>, static_cast<T &&>(t)} { using namespace hooks; hook_result_construction(this, static_cast<T &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), // BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>)) constexpr basic_result(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept( noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT : base{in_place_type<typename base::error_type>, make_error_code(t)} { using namespace hooks; hook_result_construction(this, static_cast<ErrorCondEnum &&>(t)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_result, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), // BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_result, std::decay_t<T>>{}(std::declval<T>()))) constexpr explicit basic_result(T &&o, explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT : basic_result{convert::value_or_error<basic_result, std::decay_t<T>>{}(static_cast<T &&>(o))} { } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>)) constexpr explicit basic_result( const basic_result<T, U, V> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>) : base{typename base::compatible_conversion_tag(), o} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>)) constexpr explicit basic_result( basic_result<T, U, V> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>) : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} { using namespace hooks; hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>)) constexpr explicit basic_result(const basic_result<T, U, V> &o, explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ = explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&noexcept(make_error_code(std::declval<U>()))) : base{typename base::make_error_code_compatible_conversion_tag(), o} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>)) constexpr explicit basic_result(basic_result<T, U, V> &&o, explicit_make_error_code_compatible_move_conversion_tag /*unused*/ = explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&noexcept(make_error_code(std::declval<U>()))) : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} { using namespace hooks; hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>)) constexpr explicit basic_result(const basic_result<T, U, V> &o, explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&noexcept(make_exception_ptr(std::declval<U>()))) : base{typename base::make_exception_ptr_compatible_conversion_tag(), o} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T, class U, class V) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>)) constexpr explicit basic_result(basic_result<T, U, V> &&o, explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&noexcept(make_exception_ptr(std::declval<U>()))) : base{typename base::make_exception_ptr_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} { using namespace hooks; hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>)) constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>) : base{_, static_cast<Args &&>(args)...} { using namespace hooks; hook_result_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class U, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>)) constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>) : base{_, il, static_cast<Args &&>(args)...} { using namespace hooks; hook_result_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>)) constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>) : base{_, static_cast<Args &&>(args)...} { using namespace hooks; hook_result_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class U, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>)) constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>) : base{_, il, static_cast<Args &&>(args)...} { using namespace hooks; hook_result_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_constructor<A1, A2, Args...>)) constexpr basic_result(A1 &&a1, A2 &&a2, Args &&... args) noexcept(noexcept( typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), std::declval<Args>()...))) : basic_result(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1), static_cast<A2 &&>(a2), static_cast<Args &&>(args)...) { /* I was a little surprised that the below is needed given that we forward to another constructor. But it turns out that ADL only fires on the first constructor for some reason. */ using namespace hooks; // hook_result_in_place_construction(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, this); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ constexpr basic_result(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT : base{in_place_type<value_type_if_enabled>} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, void, void>)) constexpr basic_result(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(o)} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void>)) constexpr basic_result(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))} { using namespace hooks; hook_result_move_construction(this, static_cast<success_type<T> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>)) constexpr basic_result(const failure_type<T> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept( detail::is_nothrow_constructible<error_type, T>) // NOLINT : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(o)} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>)) constexpr basic_result(failure_type<T> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept( detail::is_nothrow_constructible<error_type, T>) // NOLINT : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))} { using namespace hooks; hook_result_move_construction(this, static_cast<failure_type<T> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>)) constexpr basic_result(const failure_type<T> &o, explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ = explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(o))} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>)) constexpr basic_result(failure_type<T> &&o, explicit_make_error_code_compatible_move_conversion_tag /*unused*/ = explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))} { using namespace hooks; hook_result_move_construction(this, static_cast<failure_type<T> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>)) constexpr basic_result(const failure_type<T> &o, explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(o))} { using namespace hooks; hook_result_copy_construction(this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ BOOST_OUTCOME_TEMPLATE(class T) BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>)) constexpr basic_result(failure_type<T> &&o, explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))} { using namespace hooks; hook_result_move_construction(this, static_cast<failure_type<T> &&>(o)); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ constexpr void swap(basic_result &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) // && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value)) { constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value; constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value; detail::basic_result_storage_swap<value_throws, error_throws>(*this, o); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ auto as_failure() const & { return failure(this->assume_error()); } /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ auto as_failure() && { return failure(static_cast<basic_result &&>(*this).assume_error()); } #ifdef __APPLE__ failure_type<error_type> _xcode_workaround_as_failure() &&; #endif }; /*! AWAITING HUGO JSON CONVERSION TOOL SIGNATURE NOT RECOGNISED */ template <class R, class S, class P> inline void swap(basic_result<R, S, P> &a, basic_result<R, S, P> &b) noexcept(noexcept(a.swap(b))) { a.swap(b); } #if !defined(NDEBUG) // Check is trivial in all ways except default constructibility // static_assert(std::is_trivial<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivial!"); // static_assert(std::is_trivially_default_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially default // constructible!"); static_assert(std::is_trivially_copyable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copyable!"); static_assert(std::is_trivially_assignable<basic_result<int, long, policy::all_narrow>, basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially assignable!"); static_assert(std::is_trivially_destructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially destructible!"); static_assert(std::is_trivially_copy_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy constructible!"); static_assert(std::is_trivially_move_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move constructible!"); static_assert(std::is_trivially_copy_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy assignable!"); static_assert(std::is_trivially_move_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move assignable!"); // Also check is standard layout static_assert(std::is_standard_layout<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not a standard layout type!"); #endif BOOST_OUTCOME_V2_NAMESPACE_END #ifdef __clang__ #pragma clang diagnostic pop #endif #endif
| ver. 1.6 |
Github
|
.
| PHP 8.2.30 | ??????????? ?????????: 0.01 |
proxy
|
phpinfo
|
???????????