optional_test_map.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright (C) 2018 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. #include "boost/optional/optional.hpp"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #include "boost/core/ignore_unused.hpp"
  16. #include "boost/core/is_same.hpp"
  17. #include "boost/core/lightweight_test.hpp"
  18. #include "boost/core/lightweight_test_trait.hpp"
  19. using boost::optional;
  20. using boost::make_optional;
  21. using boost::core::is_same;
  22. template <typename Expected, typename Deduced>
  23. void verify_type(Deduced)
  24. {
  25. BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> ));
  26. }
  27. #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  28. struct MoveOnly
  29. {
  30. int value;
  31. explicit MoveOnly(int i) : value(i) {}
  32. MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; }
  33. MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; }
  34. private:
  35. MoveOnly(MoveOnly const&);
  36. void operator=(MoveOnly const&);
  37. };
  38. MoveOnly makeMoveOnly(int i)
  39. {
  40. return MoveOnly(i);
  41. }
  42. optional<MoveOnly> makeOptMoveOnly(int i)
  43. {
  44. return optional<MoveOnly>(MoveOnly(i));
  45. }
  46. int get_val(MoveOnly m)
  47. {
  48. return m.value;
  49. }
  50. void test_map_move_only()
  51. {
  52. optional<MoveOnly> om (makeMoveOnly(7)), om2 (makeMoveOnly(8));
  53. verify_type<optional<int> >(boost::move(om).map(get_val));
  54. optional<int> oi = boost::move(om2).map(get_val);
  55. BOOST_TEST(bool(oi));
  56. BOOST_TEST_EQ(8, *oi);
  57. optional<int> oj = makeOptMoveOnly(4).map(get_val);
  58. BOOST_TEST(bool(oj));
  59. BOOST_TEST_EQ(4, *oj);
  60. optional<MoveOnly> o_;
  61. optional<int> oi_ = boost::move(o_).map(get_val);
  62. BOOST_TEST(!oi_);
  63. }
  64. #endif // no rvalue refs
  65. struct Int
  66. {
  67. int i;
  68. explicit Int(int i_) : i(i_) {}
  69. };
  70. struct convert_t
  71. {
  72. typedef Int result_type;
  73. Int operator()(int i) { return Int(i); }
  74. };
  75. int& get_int_ref(Int& i)
  76. {
  77. return i.i;
  78. }
  79. struct get_ref
  80. {
  81. typedef int& result_type;
  82. int& operator()(int& i) { return i; }
  83. };
  84. void test_map()
  85. {
  86. optional<int> oi (1);
  87. verify_type<optional<Int> >(oi.map(convert_t()));
  88. optional<Int> oI = oi.map(convert_t());
  89. BOOST_TEST(bool(oI));
  90. BOOST_TEST_EQ(1, oI->i);
  91. optional<Int> o_ = optional<int>().map(convert_t());
  92. BOOST_TEST(!o_);
  93. }
  94. optional<Int> make_opt_int(int i)
  95. {
  96. if (i != 0)
  97. return Int(i);
  98. else
  99. return boost::none;
  100. }
  101. void test_map_optional()
  102. {
  103. optional<int> o9 (9), o0 (0), o_;
  104. verify_type<optional<optional<Int> > >(o9.map(make_opt_int));
  105. optional<optional<Int> > oo9 = o9.map(make_opt_int);
  106. BOOST_TEST(bool(oo9));
  107. BOOST_TEST(bool(*oo9));
  108. BOOST_TEST_EQ(9, (**oo9).i);
  109. optional<optional<Int> > oo0 = o0.map(make_opt_int);
  110. BOOST_TEST(bool(oo0));
  111. BOOST_TEST(!*oo0);
  112. optional<optional<Int> > oo_ = o_.map(make_opt_int);
  113. BOOST_TEST(!oo_);
  114. }
  115. void test_map_with_lambda()
  116. {
  117. #if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276
  118. optional<int> oi (1), oj(2);
  119. verify_type<optional<bool> >(oi.map([](int i){ return i == 1; }));
  120. optional<bool> ob = oi.map([](int i){ return i == 1; });
  121. optional<bool> oc = oj.map([](int i){ return i == 1; });
  122. BOOST_TEST(bool(ob));
  123. BOOST_TEST_EQ(true, *ob);
  124. BOOST_TEST(bool(oc));
  125. BOOST_TEST_EQ(false, *oc);
  126. #endif // lambdas
  127. }
  128. void test_map_to_ref()
  129. {
  130. optional<int> oi (2);
  131. verify_type<optional<int&> >(oi.map(get_ref()));
  132. optional<int&> ori = oi.map(get_ref());
  133. BOOST_TEST(bool(ori));
  134. *ori = 3;
  135. BOOST_TEST(bool(oi));
  136. BOOST_TEST_EQ(3, *oi);
  137. BOOST_TEST_EQ(3, *ori);
  138. }
  139. void test_map_optional_ref()
  140. {
  141. Int I (5);
  142. optional<Int&> ori (I);
  143. verify_type<optional<int&> >(ori.map(get_int_ref));
  144. optional<int&> orii = ori.map(get_int_ref);
  145. BOOST_TEST(bool(orii));
  146. BOOST_TEST_EQ(5, *orii);
  147. *orii = 6;
  148. BOOST_TEST_EQ(6, I.i);
  149. }
  150. int main()
  151. {
  152. #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  153. test_map_move_only();
  154. #endif
  155. test_map_with_lambda();
  156. test_map();
  157. test_map_optional();
  158. test_map_to_ref();
  159. test_map_optional();
  160. test_map_optional_ref();
  161. return boost::report_errors();
  162. }