/* Proposed SG14 status_code (C) 2018 - 2020 Niall Douglas (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 // 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 struct mixin : public Base { using Base::Base; }; } // namespace mixins /*! A tag for an erased value type for `status_code`. Available only if `ErasedType` satisfies `traits::is_move_bitcopying::value`. */ template ::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 : quick_status_code_from_enum_defaults { // 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 &value_mappings() { static const std::initializer_list> 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 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 struct quick_status_code_from_enum; namespace detail { template struct is_status_code { static constexpr bool value = false; }; template struct is_status_code> { static constexpr bool value = true; }; template struct is_erased_status_code { static constexpr bool value = false; }; template struct is_erased_status_code>> { static constexpr bool value = true; }; // From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf namespace impl { template struct make_void { using type = void; }; template using void_t = typename make_void::type; template struct types { using type = types; }; template