Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/json
9 : //
10 :
11 : #ifndef BOOST_JSON_RESULT_FOR_HPP
12 : #define BOOST_JSON_RESULT_FOR_HPP
13 :
14 : #include <boost/json/detail/config.hpp>
15 : #include <boost/json/fwd.hpp>
16 : #include <boost/assert/source_location.hpp>
17 : #include <boost/system/result.hpp>
18 :
19 : namespace boost {
20 : namespace json {
21 :
22 : /**
23 : Helper trait that returns @ref boost::system::result.
24 :
25 : The primary template is an incomplete type. The library provides a partial
26 : specialisation `result_for<T1, value>`, that has nested type alias `type`
27 : that aliases the type `result<T1>`.
28 :
29 : The purpose of this trait is to let users provide non-throwing conversions
30 : for their types without creating a physical dependency on Boost.Json. For
31 : example:
32 :
33 : @code
34 : namespace boost {
35 : namespace json {
36 :
37 : template<class T>
38 : struct value_to_tag;
39 :
40 : template<class T1, class T2>
41 : struct result_for;
42 : }
43 : }
44 :
45 : namespace mine
46 : {
47 : class my_class;
48 : ...
49 : template<class JsonValue>
50 : boost::json::result_for<my_class, JsonValue>
51 : tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
52 : { ... }
53 : }
54 : @endcode
55 :
56 : @see @ref try_value_to, @ref try_value_to_tag
57 : */
58 : template <class T1, class T2>
59 : struct result_for;
60 :
61 : /** Create @ref boost::system::result containing a portable error code.
62 :
63 : This function constructs a `boost::system::result<T>` that stores
64 : `error_code` with `value()` equal to `e` and `category()` equal to
65 : @ref boost::system::generic_category().
66 :
67 : The main use for this function is in implementation of functions returning
68 : `boost::system::result`, without including `boost/json/system_error.hpp` or
69 : even `<system_error>`. In particular, it may be useful for customizations
70 : of @ref try_value_to without creating a physical dependency on Boost.JSON.
71 : For example:
72 :
73 : @code
74 : #include <cerrno>
75 : #include <boost/assert/source_location.hpp>
76 :
77 : namespace boost {
78 : namespace json {
79 :
80 : class value;
81 :
82 : template<class T>
83 : struct try_value_to_tag;
84 :
85 : template<class T1, class T2>
86 : struct result_for;
87 :
88 : template <class T>
89 : typename result_for<T, value>::type
90 : result_from_errno(int e, boost::source_location const* loc) noexcept
91 :
92 : }
93 : }
94 :
95 : namespace mine {
96 :
97 : class my_class;
98 : ...
99 : template<class JsonValue>
100 : boost::json::result_for<my_class, JsonValue>
101 : tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
102 : {
103 : BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
104 : if( !jv.is_null() )
105 : return boost::json::result_from_errno<my_class>(EINVAL, &loc);
106 : return my_class();
107 : }
108 :
109 : }
110 : @endcode
111 :
112 : @par Exception Safety
113 : Does not throw exceptions.
114 :
115 : @tparam T The value type of returned `result`.
116 : @param e The error value.
117 : @param loc The error location.
118 :
119 : @returns A @ref boost::system::result containing an error.
120 :
121 : @see @ref try_value_to_tag, @ref try_value_to, @ref result_for.
122 : */
123 : template <class T>
124 : typename result_for<T, value>::type
125 56 : result_from_errno(int e, boost::source_location const* loc) noexcept
126 : {
127 56 : system::error_code ec(e, system::generic_category(), loc);
128 56 : return {system::in_place_error, ec};
129 : }
130 :
131 : } // namespace json
132 : } // namespace boost
133 :
134 : #endif // BOOST_JSON_RESULT_FOR_HPP
|