1 // Copyright (C) 2014 Andrzej Krzemienski.
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)
7 // See http://www.boost.org/lib/optional for documentation.
9 // You are welcome to contact the author at:
18 #define BOOST_ENABLE_ASSERT_HANDLER
20 #include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
21 #include "boost/mpl/bool.hpp"
22 #include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
24 #include "boost/optional/optional.hpp"
30 #include "boost/none.hpp"
32 #include "boost/test/minimal.hpp"
34 #include "optional_test_common.cpp"
39 IntWrapper(int i) : _i(i) {}
40 bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; }
44 void test_function_value_or_for()
47 const optional<T> oC0;
49 const optional<T> oC2(2);
51 BOOST_CHECK(oM0.value_or(5) == 5);
52 BOOST_CHECK(oC0.value_or(5) == 5);
53 BOOST_CHECK(oM1.value_or(5) == 1);
54 BOOST_CHECK(oC2.value_or(5) == 2);
58 void test_function_value_for()
62 const optional<T> oC(2);
76 T const& v = oC.value();
88 boost::ignore_unused(v);
90 catch(boost::bad_optional_access const&)
99 void test_function_value()
101 test_function_value_for<int>();
102 test_function_value_for<double>();
103 test_function_value_for<IntWrapper>();
106 struct FatToIntConverter
108 static int conversions;
110 FatToIntConverter(int val) : _val(val) {}
111 operator int() const { conversions += 1; return _val; }
114 int FatToIntConverter::conversions = 0;
116 void test_function_value_or()
118 test_function_value_or_for<int>();
119 test_function_value_or_for<double>();
120 test_function_value_or_for<IntWrapper>();
123 BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 1);
124 BOOST_CHECK(FatToIntConverter::conversions == 0);
127 BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 2);
128 BOOST_CHECK(FatToIntConverter::conversions == 1);
134 int operator()() { return 5; }
139 int operator()() const { return 6; }
152 void test_function_value_or_eval()
154 optional<int> o1 = 1;
159 BOOST_CHECK(o1.value_or_eval(funM) == 1);
160 BOOST_CHECK(oN.value_or_eval(funM) == 5);
161 BOOST_CHECK(o1.value_or_eval(FunM()) == 1);
162 BOOST_CHECK(oN.value_or_eval(FunM()) == 5);
164 BOOST_CHECK(o1.value_or_eval(funC) == 1);
165 BOOST_CHECK(oN.value_or_eval(funC) == 6);
166 BOOST_CHECK(o1.value_or_eval(FunC()) == 1);
167 BOOST_CHECK(oN.value_or_eval(FunC()) == 6);
169 BOOST_CHECK(o1.value_or_eval(funP) == 1);
170 BOOST_CHECK(oN.value_or_eval(funP) == 7);
172 #ifndef BOOST_NO_CXX11_LAMBDAS
173 BOOST_CHECK(o1.value_or_eval([](){return 8;}) == 1);
174 BOOST_CHECK(oN.value_or_eval([](){return 8;}) == 8);
179 BOOST_CHECK(o1.value_or_eval(throw_) == 1);
188 BOOST_CHECK(oN.value_or_eval(throw_) == 1);
197 const optional<std::string> makeConstOptVal()
199 return std::string("something");
202 void test_const_move()
204 std::string s5 = *makeConstOptVal();
205 std::string s6 = makeConstOptVal().value();
206 boost::ignore_unused(s5);
207 boost::ignore_unused(s6);
211 #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
214 explicit MoveOnly(int){}
215 MoveOnly(MoveOnly &&){}
216 void operator=(MoveOnly &&);
218 MoveOnly(MoveOnly const&);
219 void operator=(MoveOnly const&);
222 optional<MoveOnly> makeMoveOnly()
227 MoveOnly moveOnlyDefault()
233 void test_move_only_getters()
235 MoveOnly m1 = *makeMoveOnly();
236 MoveOnly m2 = makeMoveOnly().value();
237 MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
238 MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault);
239 boost::ignore_unused(m1);
240 boost::ignore_unused(m2);
241 boost::ignore_unused(m3);
242 boost::ignore_unused(m4);
245 #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
247 int test_main( int, char* [] )
251 test_function_value();
252 test_function_value_or();
253 test_function_value_or_eval();
258 BOOST_ERROR("Unexpected Exception caught!");