123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
- // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/json
- //
- #ifndef BOOST_JSON_SYSTEM_ERROR_HPP
- #define BOOST_JSON_SYSTEM_ERROR_HPP
- #include <boost/json/detail/config.hpp>
- #include <boost/json/fwd.hpp>
- #include <boost/assert/source_location.hpp>
- #include <boost/system/error_code.hpp>
- #include <boost/system/result.hpp>
- #include <boost/system/system_error.hpp>
- namespace boost {
- namespace json {
- /// The type of error code used by the library.
- using error_code = boost::system::error_code;
- /// The type of error category used by the library.
- using error_category = boost::system::error_category;
- /// The type of error condition used by the library.
- using error_condition = boost::system::error_condition;
- /// The type of system error thrown by the library.
- using system_error = boost::system::system_error;
- /** The type of result returned by library functions
- This is an alias template used as the return type for functions that can
- either return a value, or fail with an error code. This is a brief
- synopsis of the type:
- @par Declaration
- @code
- template< class T >
- class result
- {
- public:
- // Return true if the result contains an error
- constexpr bool has_error() const noexcept;
- // These two return true if the result contains a value
- constexpr bool has_value() const noexcept;
- constexpr explicit operator bool() const noexcept;
- // Return the value or throw an exception if has_value() == false
- constexpr T& value();
- constexpr T const& value() const;
- // Return the value, assuming the result contains it
- constexpr T& operator*();
- constexpr T const& operator*() const;
- // Return the error, which is default constructed if has_error() == false
- constexpr error_code error() const noexcept;
- ...more
- };
- @endcode
- @par Usage
- Given the function @ref try_value_to with this signature:
- @code
- template< class T>
- result< T > try_value_to( const value& jv );
- @endcode
- The following statement captures the value in a variable upon success,
- otherwise throws:
- @code
- int n = try_value_to<int>( jv ).value();
- @endcode
- This statement captures the result in a variable and inspects the error
- condition:
- @code
- result< int > r = try_value_to<int>( jv );
- if( r )
- std::cout << *r;
- else
- std::cout << r.error();
- @endcode
- @note For a full synopsis of the type, please see the corresponding
- documentation in Boost.System.
- @tparam T The type of value held by the result.
- */
- template< class T >
- using result = boost::system::result<T>;
- /**
- Helper trait that returns @ref result
- The primary template is an incomplete type. The library provides a partial
- specialisation `result_for<T1, value>`, that has nested type alias `type`
- that aliases the type `result<T1>`.
- The purpose of this trait is to let users provide non-throwing conversions
- for their types without creating a physical dependency on Boost.Json. For
- example:
- @code
- namespace boost
- {
- namespace json
- {
- template<class T>
- struct value_to_tag;
- template<class T1, class T2>
- struct result_for;
- }
- }
- namespace mine
- {
- class my_class;
- ...
- template<class JsonValue>
- boost::json::result_for<my_class, JsonValue>
- tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
- { ... }
- }
- @endcode
- @see @ref try_value_to, @ref try_value_to_tag
- */
- template <class T1, class T2>
- struct result_for;
- /** Create @ref result storing a portable error code
- This function constructs a `result<T>` that stores @ref error_code with
- `value()` equal to `e` and `category()` equal to
- `boost::system::generic_category()`. <br>
- The main use for this function is in implementation of functions returning
- @ref result, without including `boost/json/system_error.hpp` or even
- `<system_error>`. In particular, it may be useful for customizations of
- @ref try_value_to without creating a physical dependency on Boost.JSON.
- For example:
- @code
- #include <cerrno>
- #include <boost/assert/source_location.hpp>
- namespace boost
- {
- namespace json
- {
- class value;
- template<class T>
- struct try_value_to_tag;
- template<class T1, class T2>
- struct result_for;
- template <class T>
- typename result_for<T, value>::type
- result_from_errno(int e, boost::source_location const* loc) noexcept
- }
- }
- namespace mine
- {
- class my_class;
- ...
- template<class JsonValue>
- boost::json::result_for<my_class, JsonValue>
- tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
- {
- BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
- if( !jv.is_null() )
- return boost::json::result_from_errno<my_class>(EINVAL, &loc);
- return my_class();
- }
- }
- @endcode
- @par Exception Safety
- Does not throw exceptions.
- @tparam T The value type of returned `result`.
- @param e The error value.
- @param loc The error location.
- @returns @ref error_code with `value()` equal to `e` and `category()` equal
- to `boost::system::generic_category()`.
- @see @ref try_value_to_tag, @ref try_value_to, @ref result_for,
- <a href="https://www.boost.org/doc/libs/develop/libs/system/doc/html/system.html#ref_generic_category">
- `boost::system::generic_category`</a>,
- <a href="https://www.boost.org/doc/libs/master/libs/assert/doc/html/assert.html#source_location_support">
- `boost::source_location`</a>.
- */
- template <class T>
- typename result_for<T, value>::type
- result_from_errno(int e, boost::source_location const* loc) noexcept
- {
- error_code ec(e, system::generic_category(), loc);
- return {system::in_place_error, ec};
- }
- } // namespace json
- } // namespace boost
- #endif
|