1// Copyright 2017, 2021 Peter Dimov.
2// Distributed under the Boost Software License, Version 1.0.
3// https://www.boost.org/LICENSE_1_0.txt
4
5#include <boost/system/result.hpp>
6#include <boost/core/lightweight_test.hpp>
7#include <boost/core/lightweight_test_trait.hpp>
8#include <string>
9#include <cerrno>
10
11using namespace boost::system;
12
13struct X
14{
15 static int instances;
16
17 int v_;
18
19 X(): v_() { ++instances; }
20
21 explicit X( int v ): v_( v ) { ++instances; }
22
23 X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
24 X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
25
26 X( X const& r ): v_( r.v_ ) { ++instances; }
27
28 X& operator=( X const& ) = delete;
29
30 ~X() { --instances; }
31};
32
33int X::instances = 0;
34
35int main()
36{
37 {
38 auto ec = make_error_code( e: errc::invalid_argument );
39
40 result<int> r( ec );
41
42 BOOST_TEST( !r.has_value() );
43 BOOST_TEST( r.has_error() );
44
45 BOOST_TEST_EQ( r.error(), ec );
46 }
47
48 {
49 auto ec = make_error_code( e: errc::invalid_argument );
50
51 result<int> r = ec;
52
53 BOOST_TEST( !r.has_value() );
54 BOOST_TEST( r.has_error() );
55
56 BOOST_TEST_EQ( r.error(), ec );
57 }
58
59 {
60 result<int> r( EINVAL, generic_category() );
61
62 BOOST_TEST( !r.has_value() );
63 BOOST_TEST( r.has_error() );
64
65 BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
66 }
67
68 {
69 auto ec = make_error_code( e: errc::invalid_argument );
70
71 result<error_code> r( in_place_error, ec );
72
73 BOOST_TEST( !r.has_value() );
74 BOOST_TEST( r.has_error() );
75
76 BOOST_TEST_EQ( r.error(), ec );
77 }
78
79 {
80 result<error_code> r( in_place_error, EINVAL, generic_category() );
81
82 BOOST_TEST( !r.has_value() );
83 BOOST_TEST( r.has_error() );
84
85 BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
86 }
87
88 BOOST_TEST_EQ( X::instances, 0 );
89
90 {
91 result<std::string, X> r( 1 );
92
93 BOOST_TEST( !r.has_value() );
94 BOOST_TEST( r.has_error() );
95
96 BOOST_TEST_EQ( r.error().v_, 1 );
97
98 BOOST_TEST_EQ( X::instances, 1 );
99 }
100
101 BOOST_TEST_EQ( X::instances, 0 );
102
103 {
104 result<int, X> r( 1, 2 );
105
106 BOOST_TEST( !r.has_value() );
107 BOOST_TEST( r.has_error() );
108
109 BOOST_TEST_EQ( r.error().v_, 1+2 );
110
111 BOOST_TEST_EQ( X::instances, 1 );
112 }
113
114 BOOST_TEST_EQ( X::instances, 0 );
115
116 {
117 result<int, X> r( 1, 2, 3 );
118
119 BOOST_TEST( !r.has_value() );
120 BOOST_TEST( r.has_error() );
121
122 BOOST_TEST_EQ( r.error().v_, 1+2+3 );
123
124 BOOST_TEST_EQ( X::instances, 1 );
125 }
126
127 BOOST_TEST_EQ( X::instances, 0 );
128
129 {
130 result<X, X> r( in_place_error, 1 );
131
132 BOOST_TEST( !r.has_value() );
133 BOOST_TEST( r.has_error() );
134
135 BOOST_TEST_EQ( r.error().v_, 1 );
136
137 BOOST_TEST_EQ( X::instances, 1 );
138 }
139
140 BOOST_TEST_EQ( X::instances, 0 );
141
142 {
143 BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int>, error_code>));
144 BOOST_TEST_TRAIT_TRUE((std::is_convertible<error_code, result<int>>));
145
146 BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<std::string, X>, int>));
147 BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<std::string, X>>));
148
149 // We'd like this to be false due to the ambiguity caused by X having
150 // an explicit constructor taking an int, which should be viable in this
151 // context, but the implicit constructor is enabled, and there's no way to
152 // disallow it
153 //
154 // BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, X>, int>));
155
156 BOOST_TEST_TRAIT_TRUE((std::is_convertible<int, result<int, X>>));
157 }
158
159 {
160 auto ec = make_error_code( e: errc::invalid_argument );
161
162 result<void> r( ec );
163
164 BOOST_TEST( !r.has_value() );
165 BOOST_TEST( r.has_error() );
166
167 BOOST_TEST_EQ( r.error(), ec );
168 }
169
170 {
171 auto ec = make_error_code( e: errc::invalid_argument );
172
173 result<void> r = ec;
174
175 BOOST_TEST( !r.has_value() );
176 BOOST_TEST( r.has_error() );
177
178 BOOST_TEST_EQ( r.error(), ec );
179 }
180
181 {
182 result<void> r( EINVAL, generic_category() );
183
184 BOOST_TEST( !r.has_value() );
185 BOOST_TEST( r.has_error() );
186
187 BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
188 }
189
190 return boost::report_errors();
191}
192

source code of boost/libs/system/test/result_error_construct.cpp