]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2014 Andrzej Krzemienski. |
2 | // | |
3 | // Use, modification, and distribution is subject to the Boost Software | |
4 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | // See http://www.boost.org/lib/optional for documentation. | |
8 | // | |
9 | // You are welcome to contact the author at: | |
10 | // akrzemi1@gmail.com | |
11 | ||
12 | #include "boost/optional/optional.hpp" | |
13 | ||
20effc67 | 14 | #ifdef BOOST_BORLANDC |
7c673cae FG |
15 | #pragma hdrstop |
16 | #endif | |
17 | ||
18 | #include "boost/core/ignore_unused.hpp" | |
19 | #include "boost/core/lightweight_test.hpp" | |
20 | ||
21 | using boost::optional; | |
22 | ||
23 | struct IntWrapper | |
24 | { | |
25 | int _i; | |
26 | IntWrapper(int i) : _i(i) {} | |
27 | bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; } | |
28 | }; | |
29 | ||
30 | template <typename T> | |
31 | void test_function_value_or_for() | |
32 | { | |
33 | optional<T> oM0; | |
34 | const optional<T> oC0; | |
35 | optional<T> oM1(1); | |
36 | const optional<T> oC2(2); | |
37 | ||
38 | BOOST_TEST(oM0.value_or(5) == 5); | |
39 | BOOST_TEST(oC0.value_or(5) == 5); | |
40 | BOOST_TEST(oM1.value_or(5) == 1); | |
41 | BOOST_TEST(oC2.value_or(5) == 2); | |
42 | } | |
43 | ||
44 | template <typename T> | |
45 | void test_function_value_for() | |
46 | { | |
47 | optional<T> o0; | |
48 | optional<T> o1(1); | |
49 | const optional<T> oC(2); | |
50 | ||
51 | try | |
52 | { | |
53 | T& v = o1.value(); | |
54 | BOOST_TEST(v == 1); | |
55 | } | |
56 | catch(...) | |
57 | { | |
58 | BOOST_TEST(false); | |
59 | } | |
60 | ||
61 | try | |
62 | { | |
63 | T const& v = oC.value(); | |
64 | BOOST_TEST(v == 2); | |
65 | } | |
66 | catch(...) | |
67 | { | |
68 | BOOST_TEST(false); | |
69 | } | |
70 | ||
71 | BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access); | |
72 | } | |
73 | ||
74 | void test_function_value() | |
75 | { | |
76 | test_function_value_for<int>(); | |
77 | test_function_value_for<double>(); | |
78 | test_function_value_for<IntWrapper>(); | |
79 | } | |
80 | ||
81 | struct FatToIntConverter | |
82 | { | |
83 | static int conversions; | |
84 | int _val; | |
85 | FatToIntConverter(int val) : _val(val) {} | |
86 | operator int() const { conversions += 1; return _val; } | |
87 | }; | |
88 | ||
89 | int FatToIntConverter::conversions = 0; | |
90 | ||
91 | void test_function_value_or() | |
92 | { | |
93 | test_function_value_or_for<int>(); | |
94 | test_function_value_or_for<double>(); | |
95 | test_function_value_or_for<IntWrapper>(); | |
96 | ||
97 | optional<int> oi(1); | |
98 | BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1); | |
99 | BOOST_TEST(FatToIntConverter::conversions == 0); | |
100 | ||
101 | oi = boost::none; | |
102 | BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2); | |
103 | BOOST_TEST(FatToIntConverter::conversions == 1); | |
104 | } | |
105 | ||
106 | ||
107 | struct FunM | |
108 | { | |
109 | int operator()() { return 5; } | |
110 | }; | |
111 | ||
112 | struct FunC | |
113 | { | |
114 | int operator()() const { return 6; } | |
115 | }; | |
116 | ||
117 | int funP () | |
118 | { | |
119 | return 7; | |
120 | } | |
121 | ||
122 | int throw_() | |
123 | { | |
124 | throw int(); | |
125 | } | |
126 | ||
127 | void test_function_value_or_eval() | |
128 | { | |
129 | optional<int> o1 = 1; | |
130 | optional<int> oN; | |
131 | FunM funM; | |
132 | FunC funC; | |
133 | ||
134 | BOOST_TEST_EQ(o1.value_or_eval(funM), 1); | |
135 | BOOST_TEST_EQ(oN.value_or_eval(funM), 5); | |
136 | BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1); | |
137 | BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5); | |
138 | ||
139 | BOOST_TEST_EQ(o1.value_or_eval(funC), 1); | |
140 | BOOST_TEST_EQ(oN.value_or_eval(funC), 6); | |
141 | BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1); | |
142 | BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6); | |
143 | ||
144 | BOOST_TEST_EQ(o1.value_or_eval(funP), 1); | |
145 | BOOST_TEST_EQ(oN.value_or_eval(funP), 7); | |
146 | ||
147 | #ifndef BOOST_NO_CXX11_LAMBDAS | |
148 | BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1); | |
149 | BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8); | |
150 | #endif | |
151 | ||
152 | try | |
153 | { | |
154 | BOOST_TEST_EQ(o1.value_or_eval(throw_), 1); | |
155 | } | |
156 | catch(...) | |
157 | { | |
158 | BOOST_TEST(false); | |
159 | } | |
160 | ||
161 | BOOST_TEST_THROWS(oN.value_or_eval(throw_), int); | |
162 | } | |
163 | ||
164 | const optional<std::string> makeConstOptVal() | |
165 | { | |
166 | return std::string("something"); | |
167 | } | |
168 | ||
169 | void test_const_move() | |
170 | { | |
171 | std::string s5 = *makeConstOptVal(); | |
172 | std::string s6 = makeConstOptVal().value(); | |
173 | boost::ignore_unused(s5); | |
174 | boost::ignore_unused(s6); | |
175 | } | |
176 | ||
177 | ||
178 | #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) | |
179 | struct MoveOnly | |
180 | { | |
181 | explicit MoveOnly(int){} | |
182 | MoveOnly(MoveOnly &&){} | |
183 | void operator=(MoveOnly &&); | |
184 | private: | |
185 | MoveOnly(MoveOnly const&); | |
186 | void operator=(MoveOnly const&); | |
187 | }; | |
188 | ||
189 | optional<MoveOnly> makeMoveOnly() | |
190 | { | |
191 | return MoveOnly(1); | |
192 | } | |
193 | ||
194 | MoveOnly moveOnlyDefault() | |
195 | { | |
196 | return MoveOnly(1); | |
197 | } | |
198 | ||
199 | // compile-time test | |
200 | void test_move_only_getters() | |
201 | { | |
202 | MoveOnly m1 = *makeMoveOnly(); | |
203 | MoveOnly m2 = makeMoveOnly().value(); | |
204 | MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1)); | |
205 | MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault); | |
206 | boost::ignore_unused(m1); | |
207 | boost::ignore_unused(m2); | |
208 | boost::ignore_unused(m3); | |
209 | boost::ignore_unused(m4); | |
210 | } | |
211 | ||
212 | #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS | |
213 | ||
214 | int main() | |
215 | { | |
216 | test_function_value(); | |
217 | test_function_value_or(); | |
218 | test_function_value_or_eval(); | |
219 | test_const_move(); | |
220 | ||
221 | return boost::report_errors(); | |
222 | } |