optional_test_old_impl.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright (C) 2014 - 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. #define BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL // does old implementation still work for basic usage?
  12. #include "boost/optional/optional.hpp"
  13. #ifdef __BORLANDC__
  14. #pragma hdrstop
  15. #endif
  16. #include "boost/core/ignore_unused.hpp"
  17. #include "boost/core/lightweight_test.hpp"
  18. using boost::optional;
  19. struct IntWrapper
  20. {
  21. int _i;
  22. IntWrapper(int i) : _i(i) {}
  23. bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; }
  24. };
  25. template <typename T>
  26. void test_function_value_or_for()
  27. {
  28. optional<T> oM0;
  29. const optional<T> oC0;
  30. optional<T> oM1(1);
  31. const optional<T> oC2(2);
  32. BOOST_TEST(oM0.value_or(5) == 5);
  33. BOOST_TEST(oC0.value_or(5) == 5);
  34. BOOST_TEST(oM1.value_or(5) == 1);
  35. BOOST_TEST(oC2.value_or(5) == 2);
  36. }
  37. template <typename T>
  38. void test_function_value_for()
  39. {
  40. optional<T> o0;
  41. optional<T> o1(1);
  42. const optional<T> oC(2);
  43. try
  44. {
  45. T& v = o1.value();
  46. BOOST_TEST(v == 1);
  47. }
  48. catch(...)
  49. {
  50. BOOST_TEST(false);
  51. }
  52. try
  53. {
  54. T const& v = oC.value();
  55. BOOST_TEST(v == 2);
  56. }
  57. catch(...)
  58. {
  59. BOOST_TEST(false);
  60. }
  61. BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access);
  62. }
  63. void test_function_value()
  64. {
  65. test_function_value_for<int>();
  66. test_function_value_for<double>();
  67. test_function_value_for<IntWrapper>();
  68. }
  69. struct FatToIntConverter
  70. {
  71. static int conversions;
  72. int _val;
  73. FatToIntConverter(int val) : _val(val) {}
  74. operator int() const { conversions += 1; return _val; }
  75. };
  76. int FatToIntConverter::conversions = 0;
  77. void test_function_value_or()
  78. {
  79. test_function_value_or_for<int>();
  80. test_function_value_or_for<double>();
  81. test_function_value_or_for<IntWrapper>();
  82. optional<int> oi(1);
  83. BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1);
  84. BOOST_TEST(FatToIntConverter::conversions == 0);
  85. oi = boost::none;
  86. BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2);
  87. BOOST_TEST(FatToIntConverter::conversions == 1);
  88. }
  89. struct FunM
  90. {
  91. int operator()() { return 5; }
  92. };
  93. struct FunC
  94. {
  95. int operator()() const { return 6; }
  96. };
  97. int funP ()
  98. {
  99. return 7;
  100. }
  101. int throw_()
  102. {
  103. throw int();
  104. }
  105. void test_function_value_or_eval()
  106. {
  107. optional<int> o1 = 1;
  108. optional<int> oN;
  109. FunM funM;
  110. FunC funC;
  111. BOOST_TEST_EQ(o1.value_or_eval(funM), 1);
  112. BOOST_TEST_EQ(oN.value_or_eval(funM), 5);
  113. BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1);
  114. BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5);
  115. BOOST_TEST_EQ(o1.value_or_eval(funC), 1);
  116. BOOST_TEST_EQ(oN.value_or_eval(funC), 6);
  117. BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1);
  118. BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6);
  119. BOOST_TEST_EQ(o1.value_or_eval(funP), 1);
  120. BOOST_TEST_EQ(oN.value_or_eval(funP), 7);
  121. #ifndef BOOST_NO_CXX11_LAMBDAS
  122. BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1);
  123. BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8);
  124. #endif
  125. try
  126. {
  127. BOOST_TEST_EQ(o1.value_or_eval(throw_), 1);
  128. }
  129. catch(...)
  130. {
  131. BOOST_TEST(false);
  132. }
  133. BOOST_TEST_THROWS(oN.value_or_eval(throw_), int);
  134. }
  135. const optional<std::string> makeConstOptVal()
  136. {
  137. return std::string("something");
  138. }
  139. void test_const_move()
  140. {
  141. std::string s5 = *makeConstOptVal();
  142. std::string s6 = makeConstOptVal().value();
  143. boost::ignore_unused(s5);
  144. boost::ignore_unused(s6);
  145. }
  146. #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  147. struct MoveOnly
  148. {
  149. explicit MoveOnly(int){}
  150. MoveOnly(MoveOnly &&){}
  151. void operator=(MoveOnly &&);
  152. private:
  153. MoveOnly(MoveOnly const&);
  154. void operator=(MoveOnly const&);
  155. };
  156. optional<MoveOnly> makeMoveOnly()
  157. {
  158. return MoveOnly(1);
  159. }
  160. MoveOnly moveOnlyDefault()
  161. {
  162. return MoveOnly(1);
  163. }
  164. // compile-time test
  165. void test_move_only_getters()
  166. {
  167. MoveOnly m1 = *makeMoveOnly();
  168. MoveOnly m2 = makeMoveOnly().value();
  169. MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
  170. MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault);
  171. boost::ignore_unused(m1);
  172. boost::ignore_unused(m2);
  173. boost::ignore_unused(m3);
  174. boost::ignore_unused(m4);
  175. }
  176. #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
  177. int main()
  178. {
  179. test_function_value();
  180. test_function_value_or();
  181. test_function_value_or_eval();
  182. test_const_move();
  183. return boost::report_errors();
  184. }