| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | // Copyright (C) 2018 Andrzej Krzemienski.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Use, modification, and distribution is subject to the Boost Software
 | 
					
						
							|  |  |  | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
					
						
							|  |  |  | // http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // See http://www.boost.org/lib/optional for documentation.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You are welcome to contact the author at:
 | 
					
						
							|  |  |  | //  akrzemi1@gmail.com
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "boost/optional/optional.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-30 14:04:35 -04:00
										 |  |  | #ifdef BOOST_BORLANDC
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | #pragma hdrstop
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "boost/core/ignore_unused.hpp"
 | 
					
						
							|  |  |  | #include "boost/core/lightweight_test.hpp"
 | 
					
						
							|  |  |  | #include "boost/core/lightweight_test_trait.hpp"
 | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  | #include "boost/type_traits/is_same.hpp"
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using boost::optional; | 
					
						
							|  |  |  | using boost::make_optional; | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  | using boost::is_same; | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <typename Expected, typename Deduced> | 
					
						
							|  |  |  | void verify_type(Deduced) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> )); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | struct MoveOnly | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int value; | 
					
						
							|  |  |  |   explicit MoveOnly(int i) : value(i) {} | 
					
						
							|  |  |  |   MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; } | 
					
						
							|  |  |  |   MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; } | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | private: | 
					
						
							|  |  |  |   MoveOnly(MoveOnly const&); | 
					
						
							|  |  |  |   void operator=(MoveOnly const&); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MoveOnly makeMoveOnly(int i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return MoveOnly(i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | optional<MoveOnly> makeOptMoveOnly(int i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return optional<MoveOnly>(MoveOnly(i)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int get_val(MoveOnly m) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return m.value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void test_map_move_only() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   optional<MoveOnly> om (makeMoveOnly(7)), om2 (makeMoveOnly(8)); | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   verify_type<optional<int> >(boost::move(om).map(get_val)); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<int> oi = boost::move(om2).map(get_val); | 
					
						
							|  |  |  |   BOOST_TEST(bool(oi)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(8, *oi); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   optional<int> oj = makeOptMoveOnly(4).map(get_val); | 
					
						
							|  |  |  |   BOOST_TEST(bool(oj)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(4, *oj); | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<MoveOnly> o_; | 
					
						
							|  |  |  |   optional<int> oi_ = boost::move(o_).map(get_val); | 
					
						
							|  |  |  |   BOOST_TEST(!oi_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // no rvalue refs
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct Int | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   explicit Int(int i_) : i(i_) {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct convert_t | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-24 17:12:38 +02:00
										 |  |  |   typedef Int result_type; | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   Int operator()(int i) { return Int(i); } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int& get_int_ref(Int& i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return i.i; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct get_ref | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-24 17:12:38 +02:00
										 |  |  |   typedef int& result_type; | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   int& operator()(int& i) { return i; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void test_map() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   optional<int> oi (1); | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   verify_type<optional<Int> >(oi.map(convert_t())); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<Int> oI = oi.map(convert_t()); | 
					
						
							|  |  |  |   BOOST_TEST(bool(oI)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(1, oI->i); | 
					
						
							| 
									
										
										
										
											2018-06-23 20:53:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   optional<Int> o_ = optional<int>().map(convert_t()); | 
					
						
							|  |  |  |   BOOST_TEST(!o_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | optional<Int> make_opt_int(int i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (i != 0) | 
					
						
							|  |  |  |     return Int(i); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return boost::none; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void test_map_optional() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   optional<int> o9 (9), o0 (0), o_; | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   verify_type<optional<optional<Int> > >(o9.map(make_opt_int)); | 
					
						
							|  |  |  |   optional<optional<Int> > oo9 = o9.map(make_opt_int); | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  |   BOOST_TEST(bool(oo9)); | 
					
						
							|  |  |  |   BOOST_TEST(bool(*oo9)); | 
					
						
							| 
									
										
										
										
											2018-06-23 20:53:16 +02:00
										 |  |  |   BOOST_TEST_EQ(9, (**oo9).i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   optional<optional<Int> > oo0 = o0.map(make_opt_int); | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  |   BOOST_TEST(bool(oo0)); | 
					
						
							|  |  |  |   BOOST_TEST(!*oo0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   optional<optional<Int> > oo_ = o_.map(make_opt_int); | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  |   BOOST_TEST(!oo_); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void test_map_with_lambda() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-25 22:50:00 +02:00
										 |  |  | #if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<int> oi (1), oj(2); | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   verify_type<optional<bool> >(oi.map([](int i){ return i == 1; })); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<bool> ob = oi.map([](int i){ return i == 1; }); | 
					
						
							|  |  |  |   optional<bool> oc = oj.map([](int i){ return i == 1; }); | 
					
						
							|  |  |  |   BOOST_TEST(bool(ob)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(true, *ob); | 
					
						
							|  |  |  |   BOOST_TEST(bool(oc)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(false, *oc); | 
					
						
							|  |  |  | #endif // lambdas
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void test_map_to_ref() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   optional<int> oi (2); | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   verify_type<optional<int&> >(oi.map(get_ref())); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<int&> ori = oi.map(get_ref()); | 
					
						
							|  |  |  |   BOOST_TEST(bool(ori)); | 
					
						
							|  |  |  |   *ori = 3; | 
					
						
							|  |  |  |   BOOST_TEST(bool(oi)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(3, *oi); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(3, *ori); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void test_map_optional_ref() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Int I (5); | 
					
						
							|  |  |  |   optional<Int&> ori (I); | 
					
						
							| 
									
										
										
										
											2018-06-24 15:22:56 +02:00
										 |  |  |   verify_type<optional<int&> >(ori.map(get_int_ref)); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   optional<int&> orii = ori.map(get_int_ref); | 
					
						
							|  |  |  |   BOOST_TEST(bool(orii)); | 
					
						
							|  |  |  |   BOOST_TEST_EQ(5, *orii); | 
					
						
							|  |  |  |   *orii = 6; | 
					
						
							|  |  |  |   BOOST_TEST_EQ(6, I.i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-12-23 01:28:59 +03:00
										 |  |  | #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
 | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   test_map_move_only(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   test_map_with_lambda(); | 
					
						
							|  |  |  | 	test_map(); | 
					
						
							| 
									
										
										
										
											2018-06-23 20:53:16 +02:00
										 |  |  |   test_map_optional(); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   test_map_to_ref(); | 
					
						
							| 
									
										
										
										
											2018-06-23 20:53:16 +02:00
										 |  |  |   test_map_optional(); | 
					
						
							| 
									
										
										
										
											2018-06-23 18:27:14 +02:00
										 |  |  |   test_map_optional_ref(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return boost::report_errors(); | 
					
						
							|  |  |  | } |