optional_test_emplace.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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. #include "boost/optional/optional.hpp"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #include "boost/core/lightweight_test.hpp"
  16. #include "boost/none.hpp"
  17. //#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
  18. //#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
  19. using boost::optional;
  20. using boost::none;
  21. using boost::in_place_init;
  22. using boost::in_place_init_if;
  23. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  24. class Guard
  25. {
  26. public:
  27. int which_ctor;
  28. Guard () : which_ctor(0) { }
  29. Guard (int&, double&&) : which_ctor(1) { }
  30. Guard (int&&, double&) : which_ctor(2) { }
  31. Guard (int&&, double&&) : which_ctor(3) { }
  32. Guard (int&, double&) : which_ctor(4) { }
  33. Guard (std::string const&) : which_ctor(5) { }
  34. Guard (std::string &) : which_ctor(6) { }
  35. Guard (std::string &&) : which_ctor(7) { }
  36. private:
  37. Guard(Guard&&);
  38. Guard(Guard const&);
  39. void operator=(Guard &&);
  40. void operator=(Guard const&);
  41. };
  42. void test_emplace()
  43. {
  44. int i = 0;
  45. double d = 0.0;
  46. const std::string cs;
  47. std::string ms;
  48. optional<Guard> o;
  49. o.emplace();
  50. BOOST_TEST(o);
  51. BOOST_TEST(0 == o->which_ctor);
  52. o.emplace(i, 2.0);
  53. BOOST_TEST(o);
  54. BOOST_TEST(1 == o->which_ctor);
  55. o.emplace(1, d);
  56. BOOST_TEST(o);
  57. BOOST_TEST(2 == o->which_ctor);
  58. o.emplace(1, 2.0);
  59. BOOST_TEST(o);
  60. BOOST_TEST(3 == o->which_ctor);
  61. o.emplace(i, d);
  62. BOOST_TEST(o);
  63. BOOST_TEST(4 == o->which_ctor);
  64. o.emplace(cs);
  65. BOOST_TEST(o);
  66. BOOST_TEST(5 == o->which_ctor);
  67. o.emplace(ms);
  68. BOOST_TEST(o);
  69. BOOST_TEST(6 == o->which_ctor);
  70. o.emplace(std::string());
  71. BOOST_TEST(o);
  72. BOOST_TEST(7 == o->which_ctor);
  73. }
  74. void test_in_place_ctor()
  75. {
  76. int i = 0;
  77. double d = 0.0;
  78. const std::string cs;
  79. std::string ms;
  80. {
  81. optional<Guard> o (in_place_init);
  82. BOOST_TEST(o);
  83. BOOST_TEST(0 == o->which_ctor);
  84. }
  85. {
  86. optional<Guard> o (in_place_init, i, 2.0);
  87. BOOST_TEST(o);
  88. BOOST_TEST(1 == o->which_ctor);
  89. }
  90. {
  91. optional<Guard> o (in_place_init, 1, d);
  92. BOOST_TEST(o);
  93. BOOST_TEST(2 == o->which_ctor);
  94. }
  95. {
  96. optional<Guard> o (in_place_init, 1, 2.0);
  97. BOOST_TEST(o);
  98. BOOST_TEST(3 == o->which_ctor);
  99. }
  100. {
  101. optional<Guard> o (in_place_init, i, d);
  102. BOOST_TEST(o);
  103. BOOST_TEST(4 == o->which_ctor);
  104. }
  105. {
  106. optional<Guard> o (in_place_init, cs);
  107. BOOST_TEST(o);
  108. BOOST_TEST(5 == o->which_ctor);
  109. }
  110. {
  111. optional<Guard> o (in_place_init, ms);
  112. BOOST_TEST(o);
  113. BOOST_TEST(6 == o->which_ctor);
  114. }
  115. {
  116. optional<Guard> o (in_place_init, std::string());
  117. BOOST_TEST(o);
  118. BOOST_TEST(7 == o->which_ctor);
  119. }
  120. }
  121. void test_in_place_if_ctor()
  122. {
  123. int i = 0;
  124. double d = 0.0;
  125. const std::string cs;
  126. std::string ms;
  127. {
  128. optional<Guard> o (in_place_init_if, true);
  129. BOOST_TEST(o);
  130. BOOST_TEST(0 == o->which_ctor);
  131. }
  132. {
  133. optional<Guard> o (in_place_init_if, true, i, 2.0);
  134. BOOST_TEST(o);
  135. BOOST_TEST(1 == o->which_ctor);
  136. }
  137. {
  138. optional<Guard> o (in_place_init_if, true, 1, d);
  139. BOOST_TEST(o);
  140. BOOST_TEST(2 == o->which_ctor);
  141. }
  142. {
  143. optional<Guard> o (in_place_init_if, true, 1, 2.0);
  144. BOOST_TEST(o);
  145. BOOST_TEST(3 == o->which_ctor);
  146. }
  147. {
  148. optional<Guard> o (in_place_init_if, true, i, d);
  149. BOOST_TEST(o);
  150. BOOST_TEST(4 == o->which_ctor);
  151. }
  152. {
  153. optional<Guard> o (in_place_init_if, true, cs);
  154. BOOST_TEST(o);
  155. BOOST_TEST(5 == o->which_ctor);
  156. }
  157. {
  158. optional<Guard> o (in_place_init_if, true, ms);
  159. BOOST_TEST(o);
  160. BOOST_TEST(6 == o->which_ctor);
  161. }
  162. {
  163. optional<Guard> o (in_place_init_if, true, std::string());
  164. BOOST_TEST(o);
  165. BOOST_TEST(7 == o->which_ctor);
  166. }
  167. {
  168. optional<Guard> o (in_place_init_if, false, 1, 2.0);
  169. BOOST_TEST(!o);
  170. }
  171. }
  172. #endif
  173. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  174. struct ThrowOnMove
  175. {
  176. ThrowOnMove(ThrowOnMove&&) { throw int(); }
  177. ThrowOnMove(ThrowOnMove const&) { throw int(); }
  178. ThrowOnMove(int){}
  179. };
  180. void test_no_moves_on_emplacement()
  181. {
  182. try {
  183. optional<ThrowOnMove> o;
  184. o.emplace(1);
  185. BOOST_TEST(o);
  186. }
  187. catch (...) {
  188. BOOST_TEST(false);
  189. }
  190. }
  191. void test_no_moves_on_in_place_ctor()
  192. {
  193. try {
  194. optional<ThrowOnMove> o (in_place_init, 1);
  195. BOOST_TEST(o);
  196. optional<ThrowOnMove> p (in_place_init_if, true, 1);
  197. BOOST_TEST(p);
  198. optional<ThrowOnMove> q (in_place_init_if, false, 1);
  199. BOOST_TEST(!q);
  200. }
  201. catch (...) {
  202. BOOST_TEST(false);
  203. }
  204. }
  205. #endif
  206. struct Thrower
  207. {
  208. Thrower(bool throw_) { if (throw_) throw int(); }
  209. private:
  210. Thrower(Thrower const&);
  211. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  212. Thrower(Thrower&&);
  213. #endif
  214. };
  215. void test_clear_on_throw()
  216. {
  217. optional<Thrower> ot;
  218. try {
  219. ot.emplace(false);
  220. BOOST_TEST(ot);
  221. } catch(...) {
  222. BOOST_TEST(false);
  223. }
  224. try {
  225. ot.emplace(true);
  226. BOOST_TEST(false);
  227. } catch(...) {
  228. BOOST_TEST(!ot);
  229. }
  230. }
  231. void test_no_assignment_on_emplacement()
  232. {
  233. optional<const std::string> os, ot;
  234. BOOST_TEST(!os);
  235. os.emplace("wow");
  236. BOOST_TEST(os);
  237. BOOST_TEST_EQ(*os, "wow");
  238. BOOST_TEST(!ot);
  239. ot.emplace();
  240. BOOST_TEST(ot);
  241. BOOST_TEST_EQ(*ot, "");
  242. }
  243. namespace no_rvalue_refs {
  244. class Guard
  245. {
  246. public:
  247. int which_ctor;
  248. Guard () : which_ctor(0) { }
  249. Guard (std::string const&) : which_ctor(5) { }
  250. Guard (std::string &) : which_ctor(6) { }
  251. private:
  252. Guard(Guard const&);
  253. void operator=(Guard const&);
  254. };
  255. void test_emplace()
  256. {
  257. const std::string cs;
  258. std::string ms;
  259. optional<Guard> o;
  260. o.emplace();
  261. BOOST_TEST(o);
  262. BOOST_TEST(0 == o->which_ctor);
  263. o.emplace(cs);
  264. BOOST_TEST(o);
  265. BOOST_TEST(5 == o->which_ctor);
  266. o.emplace(ms);
  267. BOOST_TEST(o);
  268. BOOST_TEST(6 == o->which_ctor);
  269. }
  270. void test_in_place_ctor()
  271. {
  272. const std::string cs;
  273. std::string ms;
  274. {
  275. optional<Guard> o (in_place_init);
  276. BOOST_TEST(o);
  277. BOOST_TEST(0 == o->which_ctor);
  278. }
  279. {
  280. optional<Guard> o (in_place_init, cs);
  281. BOOST_TEST(o);
  282. BOOST_TEST(5 == o->which_ctor);
  283. }
  284. {
  285. optional<Guard> o (in_place_init, ms);
  286. BOOST_TEST(o);
  287. BOOST_TEST(6 == o->which_ctor);
  288. }
  289. }
  290. void test_in_place_if_ctor()
  291. {
  292. const std::string cs;
  293. std::string ms;
  294. {
  295. optional<Guard> n (in_place_init_if, false);
  296. BOOST_TEST(!n);
  297. optional<Guard> o (in_place_init_if, true);
  298. BOOST_TEST(o);
  299. BOOST_TEST(0 == o->which_ctor);
  300. }
  301. {
  302. optional<Guard> n (in_place_init_if, false, cs);
  303. BOOST_TEST(!n);
  304. optional<Guard> o (in_place_init_if, true, cs);
  305. BOOST_TEST(o);
  306. BOOST_TEST(5 == o->which_ctor);
  307. }
  308. {
  309. optional<Guard> n (in_place_init_if, false, ms);
  310. BOOST_TEST(!n);
  311. optional<Guard> o (in_place_init_if, true, ms);
  312. BOOST_TEST(o);
  313. BOOST_TEST(6 == o->which_ctor);
  314. }
  315. }
  316. } // namespace no_rvalue_ref
  317. int main()
  318. {
  319. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  320. test_emplace();
  321. test_in_place_ctor();
  322. test_in_place_if_ctor();
  323. #endif
  324. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  325. test_no_moves_on_emplacement();
  326. test_no_moves_on_in_place_ctor();
  327. #endif
  328. test_clear_on_throw();
  329. test_no_assignment_on_emplacement();
  330. no_rvalue_refs::test_emplace();
  331. no_rvalue_refs::test_in_place_ctor();
  332. no_rvalue_refs::test_in_place_if_ctor();
  333. return boost::report_errors();
  334. }