variant_tests.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. //
  5. // Copyright (C) 2018 Intel Corporation
  6. #include "../test_precomp.hpp"
  7. #include <opencv2/gapi/util/variant.hpp>
  8. #include <cstddef> //std::max_align_t
  9. namespace opencv_test
  10. {
  11. namespace
  12. {
  13. typedef util::variant<int, std::string> TestVar;
  14. typedef util::variant<int, float> TestVar2;
  15. }
  16. TEST(Variant, EmptyCTor)
  17. {
  18. util::variant<int> vi;
  19. EXPECT_EQ(0, util::get<int>(vi));
  20. util::variant<int, std::string> vis;
  21. EXPECT_EQ(0, util::get<int>(vis));
  22. util::variant<std::string> vs;
  23. EXPECT_EQ("", util::get<std::string>(vs));
  24. util::variant<std::string, int> vsi;
  25. EXPECT_EQ("", util::get<std::string>(vsi));
  26. }
  27. TEST(Variant, ConvertingCTorMove)
  28. {
  29. util::variant<int> vi(42);
  30. EXPECT_EQ(0u, vi.index());
  31. EXPECT_EQ(42, util::get<int>(vi));
  32. util::variant<int, std::string> vis(2017);
  33. EXPECT_EQ(0u, vis.index());
  34. EXPECT_EQ(2017, util::get<int>(vis));
  35. util::variant<int, std::string> vis2(std::string("2017"));
  36. EXPECT_EQ(1u, vis2.index());
  37. EXPECT_EQ("2017", util::get<std::string>(vis2));
  38. util::variant<std::string> vs(std::string("2017"));
  39. EXPECT_EQ(0u, vs.index());
  40. EXPECT_EQ("2017", util::get<std::string>(vs));
  41. util::variant<std::string, int> vsi(std::string("2017"));
  42. EXPECT_EQ(0u, vsi.index());
  43. EXPECT_EQ("2017", util::get<std::string>(vsi));
  44. std::string rvs("2017");
  45. util::variant<std::string, int> vsi3(std::move(rvs));
  46. EXPECT_EQ(0u, vsi3.index());
  47. EXPECT_EQ("2017", util::get<std::string>(vsi3));
  48. //C++ standard state that std::string instance that was moved from stays in valid, but unspecified state.
  49. //So the best assumption we can made here is that s is not the same as it was before move.
  50. EXPECT_NE("2017", rvs) <<"Rvalue source argument was not moved from while should?";
  51. util::variant<std::string, int> vsi2(42);
  52. EXPECT_EQ(1u, vsi2.index());
  53. EXPECT_EQ(42, util::get<int>(vsi2));
  54. }
  55. TEST(Variant, ConvertingCTorCopy)
  56. {
  57. const int i42 = 42;
  58. const int i17 = 2017;
  59. const std::string s17 = "2017";
  60. std::string s17_lvref = s17;
  61. util::variant<int> vi(i42);
  62. EXPECT_EQ(0u, vi.index());
  63. EXPECT_EQ(i42, util::get<int>(vi));
  64. util::variant<int, std::string> vis(i17);
  65. EXPECT_EQ(0u, vis.index());
  66. EXPECT_EQ(i17, util::get<int>(vis));
  67. util::variant<int, std::string> vis2(s17);
  68. EXPECT_EQ(1u, vis2.index());
  69. EXPECT_EQ(s17, util::get<std::string>(vis2));
  70. util::variant<std::string> vs(s17);
  71. EXPECT_EQ(0u, vs.index());
  72. EXPECT_EQ(s17, util::get<std::string>(vs));
  73. util::variant<std::string> vs_lv(s17_lvref);
  74. EXPECT_EQ(0u, vs_lv.index());
  75. EXPECT_EQ(s17, s17_lvref);
  76. EXPECT_EQ(s17_lvref, util::get<std::string>(vs_lv));
  77. util::variant<std::string, int> vsi(s17);
  78. EXPECT_EQ(0u, vsi.index());
  79. EXPECT_EQ(s17, util::get<std::string>(vsi));
  80. util::variant<std::string, int> vsi2(i42);
  81. EXPECT_EQ(1u, vsi2.index());
  82. EXPECT_EQ(i42, util::get<int>(vsi2));
  83. }
  84. TEST(Variant, CopyMoveCTor)
  85. {
  86. const TestVar tvconst(std::string("42"));
  87. TestVar tv = tvconst;
  88. EXPECT_EQ( 1u, tv.index());
  89. EXPECT_EQ("42", util::get<std::string>(tv));
  90. TestVar tv2(TestVar(40+2));
  91. EXPECT_EQ( 0u, tv2.index());
  92. EXPECT_EQ( 42, util::get<int>(tv2));
  93. }
  94. TEST(Variant, Assign_Basic)
  95. {
  96. TestVar vis;
  97. EXPECT_EQ(0u, vis.index());
  98. EXPECT_EQ(0, util::get<int>(vis));
  99. vis = 42;
  100. EXPECT_EQ(0u, vis.index());
  101. EXPECT_EQ(42, util::get<int>(vis));
  102. }
  103. TEST(Variant, Assign_LValueRef)
  104. {
  105. TestVar vis;
  106. EXPECT_EQ(0u, vis.index());
  107. EXPECT_EQ(0, util::get<int>(vis));
  108. int val = 42;
  109. vis = val;
  110. EXPECT_EQ(0u, vis.index());
  111. EXPECT_EQ(42, util::get<int>(vis));
  112. }
  113. TEST(Variant, Assign_ValueUpdate_SameType)
  114. {
  115. TestVar vis(42);
  116. EXPECT_EQ(0u, vis.index());
  117. EXPECT_EQ(42, util::get<int>(vis));
  118. vis = 43;
  119. EXPECT_EQ(0u, vis.index());
  120. EXPECT_EQ(43, util::get<int>(vis));
  121. }
  122. TEST(Variant, Assign_ValueUpdate_DiffType)
  123. {
  124. TestVar vis(42);
  125. EXPECT_EQ(0u, vis.index());
  126. EXPECT_EQ(42, util::get<int>(vis));
  127. vis = std::string("42");
  128. EXPECT_EQ(1u, vis.index());
  129. EXPECT_EQ("42", util::get<std::string>(vis));
  130. }
  131. TEST(Variant, Assign_RValueRef_DiffType)
  132. {
  133. TestVar vis(42);
  134. EXPECT_EQ(0u, vis.index());
  135. EXPECT_EQ(42, util::get<int>(vis));
  136. std::string s("42");
  137. vis = std::move(s);
  138. EXPECT_EQ(1u, vis.index());
  139. EXPECT_EQ("42", util::get<std::string>(vis));
  140. //C++ standard state that std::string instance that was moved from stays in valid, but unspecified state.
  141. //So the best assumption we can made here is that s is not the same as it was before move.
  142. EXPECT_NE("42", s) << "right hand side argument of assignment operation was not moved from while should?";
  143. }
  144. TEST(Variant, Assign_RValueRef_SameType)
  145. {
  146. TestVar vis(std::string("43"));
  147. EXPECT_EQ(1u, vis.index());
  148. EXPECT_EQ("43", util::get<std::string>(vis));
  149. std::string s("42");
  150. vis = std::move(s);
  151. EXPECT_EQ(1u, vis.index());
  152. EXPECT_EQ("42", util::get<std::string>(vis));
  153. //C++ standard state that std::string instance that was moved from stays in valid, but unspecified state.
  154. //So the best assumption we can made here is that s is not the same as it was before move.
  155. EXPECT_NE("42", s) << "right hand side argument of assignment operation was not moved from while should?";
  156. }
  157. TEST(Variant, Assign_LValueRef_DiffType)
  158. {
  159. TestVar vis(42);
  160. EXPECT_EQ(0u, vis.index());
  161. EXPECT_EQ(42, util::get<int>(vis));
  162. std::string s("42");
  163. vis = s;
  164. EXPECT_EQ(1u, vis.index());
  165. EXPECT_EQ("42", util::get<std::string>(vis));
  166. EXPECT_EQ("42", s) << "right hand side argument of assignment operation was moved from while should not ?";
  167. }
  168. TEST(Variant, Assign_ValueUpdate_Const_Variant)
  169. {
  170. TestVar va(42);
  171. const TestVar vb(43);
  172. EXPECT_EQ(0u, va.index());
  173. EXPECT_EQ(42, util::get<int>(va));
  174. EXPECT_EQ(0u, vb.index());
  175. EXPECT_EQ(43, util::get<int>(vb));
  176. va = vb;
  177. EXPECT_EQ(0u, va.index());
  178. EXPECT_EQ(43, util::get<int>(va));
  179. }
  180. TEST(Variant, Assign_ValueUpdate_Const_DiffType_Variant)
  181. {
  182. TestVar va(42);
  183. const TestVar vb(std::string("42"));
  184. EXPECT_EQ(0u, va.index());
  185. EXPECT_EQ(42, util::get<int>(va));
  186. EXPECT_EQ(1u, vb.index());
  187. EXPECT_EQ("42", util::get<std::string>(vb));
  188. va = vb;
  189. EXPECT_EQ(1u, va.index());
  190. EXPECT_EQ("42", util::get<std::string>(va));
  191. }
  192. TEST(Variant, Assign_Move_Variant)
  193. {
  194. TestVar va(42);
  195. TestVar vb(std::string("42"));
  196. TestVar vd(std::string("43"));
  197. TestVar vc(43);
  198. EXPECT_EQ(0u, va.index());
  199. EXPECT_EQ(42, util::get<int>(va));
  200. EXPECT_EQ(1u, vb.index());
  201. EXPECT_EQ("42", util::get<std::string>(vb));
  202. EXPECT_EQ(0u, vc.index());
  203. EXPECT_EQ(43, util::get<int>(vc));
  204. EXPECT_EQ(1u, vd.index());
  205. EXPECT_EQ("43", util::get<std::string>(vd));
  206. va = std::move(vb);
  207. EXPECT_EQ(1u, va.index());
  208. EXPECT_EQ("42", util::get<std::string>(va));
  209. EXPECT_EQ(1u, vb.index());
  210. EXPECT_EQ("", util::get<std::string>(vb));
  211. vb = std::move(vd);
  212. EXPECT_EQ(1u, vb.index());
  213. EXPECT_EQ("43", util::get<std::string>(vb));
  214. EXPECT_EQ(1u, vd.index());
  215. EXPECT_EQ("", util::get<std::string>(vd));
  216. va = std::move(vc);
  217. EXPECT_EQ(0u, va.index());
  218. EXPECT_EQ(43, util::get<int>(va));
  219. }
  220. TEST(Variant, Swap_SameIndex)
  221. {
  222. TestVar tv1(42);
  223. TestVar tv2(43);
  224. EXPECT_EQ(0u, tv1.index());
  225. EXPECT_EQ(42, util::get<int>(tv1));
  226. EXPECT_EQ(0u, tv2.index());
  227. EXPECT_EQ(43, util::get<int>(tv2));
  228. tv1.swap(tv2);
  229. EXPECT_EQ(0u, tv1.index());
  230. EXPECT_EQ(43, util::get<int>(tv1));
  231. EXPECT_EQ(0u, tv2.index());
  232. EXPECT_EQ(42, util::get<int>(tv2));
  233. }
  234. TEST(Variant, Swap_DiffIndex)
  235. {
  236. TestVar2 tv1(42);
  237. TestVar2 tv2(3.14f);
  238. EXPECT_EQ(0u, tv1.index());
  239. EXPECT_EQ(42, util::get<int>(tv1));
  240. EXPECT_EQ(1u, tv2.index());
  241. EXPECT_EQ(3.14f, util::get<float>(tv2));
  242. tv1.swap(tv2);
  243. EXPECT_EQ(0u, tv2.index());
  244. EXPECT_EQ(42, util::get<int>(tv2));
  245. EXPECT_EQ(1u, tv1.index());
  246. EXPECT_EQ(3.14f, util::get<float>(tv1));
  247. }
  248. TEST(Variant, GetIf)
  249. {
  250. const TestVar cv(42);
  251. // Test const& get_if()
  252. EXPECT_EQ(nullptr, util::get_if<std::string>(&cv));
  253. ASSERT_NE(nullptr, util::get_if<int>(&cv));
  254. EXPECT_EQ(42, *util::get_if<int>(&cv));
  255. // Test &get_if
  256. TestVar cv2(std::string("42"));
  257. EXPECT_EQ(nullptr, util::get_if<int>(&cv2));
  258. ASSERT_NE(nullptr, util::get_if<std::string>(&cv2));
  259. EXPECT_EQ("42", *util::get_if<std::string>(&cv2));
  260. }
  261. TEST(Variant, Get)
  262. {
  263. const TestVar cv(42);
  264. // Test const& get()
  265. EXPECT_EQ(42, util::get<int>(cv));
  266. EXPECT_THROW(util::get<std::string>(cv), util::bad_variant_access);
  267. // Test &get
  268. TestVar cv2(std::string("42"));
  269. EXPECT_EQ("42", util::get<std::string>(cv2));
  270. EXPECT_THROW(util::get<int>(cv2), util::bad_variant_access);
  271. }
  272. TEST(Variant, GetIndexed)
  273. {
  274. const TestVar cv(42);
  275. // Test const& get()
  276. EXPECT_EQ(42, util::get<0>(cv));
  277. EXPECT_THROW(util::get<1>(cv), util::bad_variant_access);
  278. // Test &get
  279. TestVar cv2(std::string("42"));
  280. EXPECT_EQ("42", util::get<1>(cv2));
  281. EXPECT_THROW(util::get<0>(cv2), util::bad_variant_access);
  282. }
  283. TEST(Variant, GetWrite)
  284. {
  285. util::variant<int, std::string> v(42);
  286. EXPECT_EQ(42, util::get<int>(v));
  287. util::get<int>(v) = 43;
  288. EXPECT_EQ(43, util::get<int>(v));
  289. }
  290. TEST(Variant, NoDefaultCtor)
  291. {
  292. struct MyType
  293. {
  294. int m_a;
  295. MyType() = delete;
  296. };
  297. // This code MUST compile
  298. util::variant<int, MyType> var;
  299. SUCCEED() << "Code compiled";
  300. // At the same time, util::variant<MyType, ...> MUST NOT.
  301. }
  302. TEST(Variant, MonoState)
  303. {
  304. struct MyType
  305. {
  306. int m_a;
  307. explicit MyType(int a) : m_a(a) {}
  308. MyType() = delete;
  309. };
  310. util::variant<util::monostate, MyType> var;
  311. EXPECT_EQ(0u, var.index());
  312. var = MyType{42};
  313. EXPECT_EQ(1u, var.index());
  314. EXPECT_EQ(42, util::get<MyType>(var).m_a);
  315. }
  316. TEST(Variant, Eq)
  317. {
  318. TestVar v1(42), v2(std::string("42"));
  319. TestVar v3(v1), v4(v2);
  320. EXPECT_TRUE(v1 == v3);
  321. EXPECT_TRUE(v2 == v4);
  322. EXPECT_TRUE(v1 != v2);
  323. EXPECT_TRUE(v3 != v4);
  324. EXPECT_FALSE(v1 == v2);
  325. EXPECT_FALSE(v3 == v4);
  326. EXPECT_FALSE(v1 != v3);
  327. EXPECT_FALSE(v2 != v4);
  328. }
  329. TEST(Variant, Eq_Monostate)
  330. {
  331. using TestVar3 = util::variant<util::monostate, int>;
  332. TestVar3 v1;
  333. TestVar3 v2(42);
  334. EXPECT_NE(v1, v2);
  335. v2 = util::monostate{};
  336. EXPECT_EQ(v1, v2);
  337. }
  338. TEST(Variant, VectorOfVariants)
  339. {
  340. std::vector<TestVar> vv1(1024);
  341. std::vector<TestVar> vv2(1024);
  342. EXPECT_TRUE(vv1 == vv2);
  343. std::vector<TestVar> vv3(2048, TestVar(std::string("42")));
  344. // Just test chat the below code compiles:
  345. // 1: internal copy of variants from one vector to another,
  346. // with probable reallocation of 1st vector to host all elements
  347. std::copy(vv1.begin(), vv1.end(), std::back_inserter(vv2));
  348. EXPECT_EQ(2048u, vv2.size());
  349. // 2: truncation of vector, with probable destruction of its tail memory
  350. vv2.resize(1024);
  351. EXPECT_EQ(1024u, vv2.size());
  352. // 3. vector assignment, with overwriting underlying variants
  353. vv2 = vv3;
  354. EXPECT_EQ(2048u, vv2.size());
  355. EXPECT_TRUE(vv2 == vv3);
  356. }
  357. TEST(Variant, HoldsAlternative)
  358. {
  359. TestVar v(42);
  360. EXPECT_TRUE (util::holds_alternative<int> (v));
  361. EXPECT_FALSE(util::holds_alternative<std::string>(v));
  362. v = std::string("42");
  363. EXPECT_FALSE(util::holds_alternative<int> (v));
  364. EXPECT_TRUE (util::holds_alternative<std::string>(v));
  365. }
  366. TEST(Variant, Sizeof)
  367. {
  368. //variant has to store index of the contained type as well as the type itself
  369. EXPECT_EQ(2 * sizeof(size_t), (sizeof(util::variant<int, char>)));
  370. #if !defined(__GNUG__) || __GNUG__ >= 5
  371. // GCC versions prior to 5.0 have limited C++11 support, e.g.
  372. // no std::max_align_t defined
  373. EXPECT_EQ((sizeof(std::max_align_t) + std::max(sizeof(size_t), alignof(std::max_align_t))), (sizeof(util::variant<std::max_align_t, char>)));
  374. #endif
  375. }
  376. TEST(Variant, EXT_IndexOf)
  377. {
  378. struct MyType{};
  379. class MyClass{};
  380. using V = util::variant<util::monostate, int, double, char, float, MyType, MyClass>;
  381. static_assert(0u == V::index_of<util::monostate>(), "Index is incorrect");
  382. static_assert(1u == V::index_of<int >(), "Index is incorrect");
  383. static_assert(2u == V::index_of<double >(), "Index is incorrect");
  384. static_assert(3u == V::index_of<char >(), "Index is incorrect");
  385. static_assert(4u == V::index_of<float >(), "Index is incorrect");
  386. static_assert(5u == V::index_of<MyType >(), "Index is incorrect");
  387. static_assert(6u == V::index_of<MyClass>(), "Index is incorrect");
  388. }
  389. namespace test_validation
  390. {
  391. struct MyType
  392. {
  393. friend std::ostream& operator<<(std::ostream& out, const MyType& src)
  394. {
  395. return out << "MyType"; (void) src;
  396. }
  397. };
  398. class MyClass
  399. {
  400. friend std::ostream& operator<<(std::ostream& out, const MyClass& src)
  401. {
  402. return out << "MyClass"; (void) src;
  403. }
  404. };
  405. struct MyBoolParamIndexedVisitor : cv::util::static_indexed_visitor<bool, MyBoolParamIndexedVisitor>
  406. {
  407. MyBoolParamIndexedVisitor(std::ostream &output) : out(output) {}
  408. template<class Type>
  409. bool visit(std::size_t index, Type val, int check)
  410. {
  411. bool result = false;
  412. out << index << ":" << val <<",";
  413. if(std::is_same<Type, int>::value)
  414. {
  415. result = !memcmp(&val, &check, sizeof(int));
  416. }
  417. return result;
  418. }
  419. std::ostream &out;
  420. };
  421. struct MyBoolNoParamNonIndexedVisitor : cv::util::static_indexed_visitor<bool, MyBoolNoParamNonIndexedVisitor>
  422. {
  423. MyBoolNoParamNonIndexedVisitor(std::ostream &output) : out(output) {}
  424. template<class Type>
  425. bool visit(std::size_t index, Type val)
  426. {
  427. out << index << ":" << val <<",";
  428. return true;
  429. }
  430. std::ostream &out;
  431. };
  432. struct MyVoidNoParamNonIndexedVisitor : cv::util::static_visitor<void, MyVoidNoParamNonIndexedVisitor>
  433. {
  434. MyVoidNoParamNonIndexedVisitor(std::ostream &output) : out(output) {}
  435. template<class Type>
  436. void visit(Type val)
  437. {
  438. out << val << ",";
  439. }
  440. std::ostream &out;
  441. };
  442. struct MyVoidNoParamIndexedVisitor : cv::util::static_indexed_visitor<void, MyVoidNoParamIndexedVisitor>
  443. {
  444. MyVoidNoParamIndexedVisitor(std::ostream &output) : out(output) {}
  445. template<class Type>
  446. void visit(std::size_t Index, Type val)
  447. {
  448. out << Index << ":" << val <<",";
  449. }
  450. std::ostream &out;
  451. };
  452. }
  453. TEST(Variant, DynamicVisitor)
  454. {
  455. using V = cv::util::variant<int, double, char, float, test_validation::MyType, test_validation::MyClass>;
  456. V var{42};
  457. {
  458. std::stringstream ss;
  459. test_validation::MyBoolParamIndexedVisitor visitor(ss);
  460. EXPECT_TRUE(cv::util::visit(visitor, var, int{42}));
  461. EXPECT_EQ(std::string("0:42,"), ss.str());
  462. }
  463. std::stringstream ss;
  464. test_validation::MyBoolNoParamNonIndexedVisitor visitor(ss);
  465. cv::util::visit(visitor, var);
  466. EXPECT_EQ(std::string("0:42,"), ss.str());
  467. var = double{1.0};
  468. EXPECT_TRUE(cv::util::visit(visitor, var));
  469. EXPECT_EQ(std::string("0:42,1:1,"), ss.str());
  470. var = char{'a'};
  471. EXPECT_TRUE(cv::util::visit(visitor, var));
  472. EXPECT_EQ(std::string("0:42,1:1,2:a,"), ss.str());
  473. var = float{6.0};
  474. EXPECT_TRUE(cv::util::visit(visitor, var));
  475. EXPECT_EQ(std::string("0:42,1:1,2:a,3:6,"), ss.str());
  476. var = test_validation::MyType{};
  477. EXPECT_TRUE(cv::util::visit(visitor, var));
  478. EXPECT_EQ(std::string("0:42,1:1,2:a,3:6,4:MyType,"), ss.str());
  479. var = test_validation::MyClass{};
  480. EXPECT_TRUE(cv::util::visit(visitor, var));
  481. EXPECT_EQ(std::string("0:42,1:1,2:a,3:6,4:MyType,5:MyClass,"), ss.str());
  482. }
  483. TEST(Variant, StaticVisitor)
  484. {
  485. using V = cv::util::variant<int, double, char, float, test_validation::MyType, test_validation::MyClass>;
  486. V var{42};
  487. std::stringstream ss;
  488. test_validation::MyVoidNoParamNonIndexedVisitor visitor(ss);
  489. cv::util::visit(visitor, var);
  490. EXPECT_EQ(std::string("42,"), ss.str());
  491. var = double{1.0};
  492. cv::util::visit(visitor, var);
  493. EXPECT_EQ(std::string("42,1,"), ss.str());
  494. var = char{'a'};
  495. cv::util::visit(visitor, var);
  496. EXPECT_EQ(std::string("42,1,a,"), ss.str());
  497. var = float{6.0};
  498. cv::util::visit(visitor, var);
  499. EXPECT_EQ(std::string("42,1,a,6,"), ss.str());
  500. var = test_validation::MyType{};
  501. cv::util::visit(visitor, var);
  502. EXPECT_EQ(std::string("42,1,a,6,MyType,"), ss.str());
  503. var = test_validation::MyClass{};
  504. cv::util::visit(visitor, var);
  505. EXPECT_EQ(std::string("42,1,a,6,MyType,MyClass,"), ss.str());
  506. }
  507. TEST(Variant, StaticIndexedVisitor)
  508. {
  509. using V = cv::util::variant<int, double, char, float, test_validation::MyType, test_validation::MyClass>;
  510. V var{42};
  511. std::stringstream ss;
  512. cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor {ss}, var);
  513. EXPECT_EQ(std::string("0:42,"), ss.str());
  514. var = double{1.0};
  515. cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var);
  516. EXPECT_EQ(std::string("0:42,1:1,"), ss.str());
  517. var = char{'a'};
  518. cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var);
  519. EXPECT_EQ(std::string("0:42,1:1,2:a,"), ss.str());
  520. var = float{6.0};
  521. cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var);
  522. EXPECT_EQ(std::string("0:42,1:1,2:a,3:6,"), ss.str());
  523. var = test_validation::MyType{};
  524. cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var);
  525. EXPECT_EQ(std::string("0:42,1:1,2:a,3:6,4:MyType,"), ss.str());
  526. var = test_validation::MyClass{};
  527. cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var);
  528. EXPECT_EQ(std::string("0:42,1:1,2:a,3:6,4:MyType,5:MyClass,"), ss.str());
  529. }
  530. TEST(Variant, LambdaVisitor)
  531. {
  532. using V = cv::util::variant<int, double, char, float, test_validation::MyType, test_validation::MyClass>;
  533. V var{42};
  534. {
  535. cv::util::visit(cv::util::overload_lambdas(
  536. [](int value) {
  537. EXPECT_EQ(42, value);
  538. },
  539. [](double) {
  540. ADD_FAILURE() << "can't be called for `double`";
  541. },
  542. [](char) {
  543. ADD_FAILURE() << "can't be called for `char`";
  544. },
  545. [](float) {
  546. ADD_FAILURE() << "can't be called for `float`";
  547. },
  548. [](test_validation::MyType) {
  549. ADD_FAILURE() << "can't be called for `MyType`";
  550. },
  551. [](test_validation::MyClass) {
  552. ADD_FAILURE() << "can't be called for `MyClass`";
  553. },
  554. [](std::string) {
  555. ADD_FAILURE() << "can't be called for `std::string`, invalid type";
  556. }
  557. ), var);
  558. }
  559. var = 'c';
  560. {
  561. cv::util::visit(cv::util::overload_lambdas(
  562. [](int) {
  563. ADD_FAILURE() << "can't be called for `int`";
  564. },
  565. [](double) {
  566. ADD_FAILURE() << "can't be called for `double`";
  567. },
  568. [](char value) {
  569. EXPECT_EQ('c', value);
  570. },
  571. [](float) {
  572. ADD_FAILURE() << "can't be called for `float`";
  573. },
  574. [](test_validation::MyType) {
  575. ADD_FAILURE() << "can't be called for `MyType`";
  576. },
  577. [](test_validation::MyClass) {
  578. ADD_FAILURE() << "can't be called for `MyClass`";
  579. },
  580. [](std::string) {
  581. ADD_FAILURE() << "can't be called for `std::string`, invalid type";
  582. }
  583. ), var);
  584. }
  585. }
  586. } // namespace opencv_test