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 BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int&, X>, int>));
150 BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<int&, X>>));
151
152 // There's an ambiguity here between int& and X, but since is_convertible
153 // is true, is_constructible can't be false.
154
155 // BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int&, X>, int&>));
156 BOOST_TEST_TRAIT_TRUE((std::is_convertible<int&, result<int&, X>>));
157 }
158
159 return boost::report_errors();
160}
161

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