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 `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 : {
36 : namespace json
37 : {
38 :
39 : template<class T>
40 : struct value_to_tag;
41 :
42 : template<class T1, class T2>
43 : struct result_for;
44 : }
45 : }
46 :
47 : namespace mine
48 : {
49 : class my_class;
50 : ...
51 : template<class JsonValue>
52 : boost::json::result_for<my_class, JsonValue>
53 : tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
54 : { ... }
55 : }
56 : @endcode
57 :
58 : @see @ref try_value_to, @ref try_value_to_tag
59 : */
60 : template <class T1, class T2>
61 : struct result_for;
62 :
63 : /** Create `boost::system::result` storing a portable error code
64 :
65 : This function constructs a `boost::system::result<T>` that stores
66 : `boost::system::error_code` with `value()` equal to `e` and `category()`
67 : equal to `boost::system::generic_category()`. <br>
68 :
69 : The main use for this function is in implementation of functions returning
70 : `boost::system::result`, without including `boost/json/system_error.hpp` or
71 : even `<system_error>`. In particular, it may be useful for customizations
72 : of @ref try_value_to without creating a physical dependency on Boost.JSON.
73 : For example:
74 :
75 : @code
76 : #include <cerrno>
77 : #include <boost/assert/source_location.hpp>
78 :
79 : namespace boost
80 : {
81 : namespace json
82 : {
83 :
84 : class value;
85 :
86 : template<class T>
87 : struct try_value_to_tag;
88 :
89 : template<class T1, class T2>
90 : struct result_for;
91 :
92 : template <class T>
93 : typename result_for<T, value>::type
94 : result_from_errno(int e, boost::source_location const* loc) noexcept
95 :
96 : }
97 : }
98 :
99 : namespace mine
100 : {
101 :
102 : class my_class;
103 : ...
104 : template<class JsonValue>
105 : boost::json::result_for<my_class, JsonValue>
106 : tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
107 : {
108 : BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
109 : if( !jv.is_null() )
110 : return boost::json::result_from_errno<my_class>(EINVAL, &loc);
111 : return my_class();
112 : }
113 :
114 : }
115 : @endcode
116 :
117 : @par Exception Safety
118 : Does not throw exceptions.
119 :
120 : @tparam T The value type of returned `result`.
121 :
122 : @param e The error value.
123 :
124 : @param loc The error location.
125 :
126 : @returns `boost::system::error_code` with `value()` equal to `e` and
127 : `category()` equal to `boost::system::generic_category()`.
128 :
129 : @see @ref try_value_to_tag, @ref try_value_to, @ref result_for,
130 : <a href="https://www.boost.org/doc/libs/develop/libs/system/doc/html/system.html#ref_generic_category">
131 : `boost::system::generic_category`</a>,
132 : <a href="https://www.boost.org/doc/libs/master/libs/assert/doc/html/assert.html#source_location_support">
133 : `boost::source_location`</a>.
134 : */
135 : template <class T>
136 : typename result_for<T, value>::type
137 62 : result_from_errno(int e, boost::source_location const* loc) noexcept
138 : {
139 62 : system::error_code ec(e, system::generic_category(), loc);
140 62 : return {system::in_place_error, ec};
141 : }
142 :
143 : } // namespace json
144 : } // namespace boost
145 :
146 : #endif // BOOST_JSON_RESULT_FOR_HPP
|