Path: blob/master/modules/gapi/test/util/variant_tests.cpp
16354 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3//4// Copyright (C) 2018 Intel Corporation567#include "test_precomp.hpp"8#include "opencv2/gapi/util/variant.hpp"9#include <cstddef> //std::max_align_t1011namespace opencv_test12{1314namespace15{16typedef util::variant<int, std::string> TestVar;17typedef util::variant<int, float> TestVar2;18}1920TEST(Variant, EmptyCTor)21{22util::variant<int> vi;23EXPECT_EQ(0, util::get<int>(vi));2425util::variant<int, std::string> vis;26EXPECT_EQ(0, util::get<int>(vis));2728util::variant<std::string> vs;29EXPECT_EQ("", util::get<std::string>(vs));3031util::variant<std::string, int> vsi;32EXPECT_EQ("", util::get<std::string>(vsi));33}3435TEST(Variant, ValueMoveCTor)36{37util::variant<int> vi(42);38EXPECT_EQ(0u, vi.index());39EXPECT_EQ(42, util::get<int>(vi));4041util::variant<int, std::string> vis(2017);42EXPECT_EQ(0u, vis.index());43EXPECT_EQ(2017, util::get<int>(vis));4445util::variant<int, std::string> vis2(std::string("2017"));46EXPECT_EQ(1u, vis2.index());47EXPECT_EQ("2017", util::get<std::string>(vis2));4849util::variant<std::string> vs(std::string("2017"));50EXPECT_EQ(0u, vs.index());51EXPECT_EQ("2017", util::get<std::string>(vs));5253util::variant<std::string, int> vsi(std::string("2017"));54EXPECT_EQ(0u, vsi.index());55EXPECT_EQ("2017", util::get<std::string>(vsi));5657util::variant<std::string, int> vsi2(42);58EXPECT_EQ(1u, vsi2.index());59EXPECT_EQ(42, util::get<int>(vsi2));60}6162TEST(Variant, ValueCopyCTor)63{64const int i42 = 42;65const int i17 = 2017;66const std::string s17 = "2017";6768util::variant<int> vi(i42);69EXPECT_EQ(0u, vi.index());70EXPECT_EQ(i42, util::get<int>(vi));7172util::variant<int, std::string> vis(i17);73EXPECT_EQ(0u, vis.index());74EXPECT_EQ(i17, util::get<int>(vis));7576util::variant<int, std::string> vis2(s17);77EXPECT_EQ(1u, vis2.index());78EXPECT_EQ(s17, util::get<std::string>(vis2));7980util::variant<std::string> vs(s17);81EXPECT_EQ(0u, vs.index());82EXPECT_EQ(s17, util::get<std::string>(vs));8384util::variant<std::string, int> vsi(s17);85EXPECT_EQ(0u, vsi.index());86EXPECT_EQ(s17, util::get<std::string>(vsi));8788util::variant<std::string, int> vsi2(i42);89EXPECT_EQ(1u, vsi2.index());90EXPECT_EQ(i42, util::get<int>(vsi2));91}9293TEST(Variant, CopyMoveCTor)94{95const TestVar tvconst(std::string("42"));9697TestVar tv = tvconst;98EXPECT_EQ( 1u, tv.index());99EXPECT_EQ("42", util::get<std::string>(tv));100101TestVar tv2(TestVar(40+2));102EXPECT_EQ( 0u, tv2.index());103EXPECT_EQ( 42, util::get<int>(tv2));104}105106TEST(Variant, Assign_Basic)107{108TestVar vis;109EXPECT_EQ(0u, vis.index());110EXPECT_EQ(0, util::get<int>(vis));111112vis = 42;113EXPECT_EQ(0u, vis.index());114EXPECT_EQ(42, util::get<int>(vis));115}116117TEST(Variant, Assign_ValueUpdate_SameType)118{119TestVar vis(42);120121EXPECT_EQ(0u, vis.index());122EXPECT_EQ(42, util::get<int>(vis));123124vis = 43;125EXPECT_EQ(0u, vis.index());126EXPECT_EQ(43, util::get<int>(vis));127}128129TEST(Variant, Assign_ValueUpdate_DiffType)130{131TestVar vis(42);132133EXPECT_EQ(0u, vis.index());134EXPECT_EQ(42, util::get<int>(vis));135136vis = std::string("42");137EXPECT_EQ(1u, vis.index());138EXPECT_EQ("42", util::get<std::string>(vis));139}140141TEST(Variant, Assign_ValueUpdate_Const)142{143TestVar va(42);144const TestVar vb(43);145146EXPECT_EQ(0u, va.index());147EXPECT_EQ(42, util::get<int>(va));148149EXPECT_EQ(0u, vb.index());150EXPECT_EQ(43, util::get<int>(vb));151152va = vb;153154EXPECT_EQ(0u, va.index());155EXPECT_EQ(43, util::get<int>(va));156}157158TEST(Variant, Assign_ValueUpdate_Const_DiffType)159{160TestVar va(42);161const TestVar vb(std::string("42"));162163EXPECT_EQ(0u, va.index());164EXPECT_EQ(42, util::get<int>(va));165166EXPECT_EQ(1u, vb.index());167EXPECT_EQ("42", util::get<std::string>(vb));168169va = vb;170171EXPECT_EQ(1u, va.index());172EXPECT_EQ("42", util::get<std::string>(va));173}174175TEST(Variant, Assign_Move)176{177TestVar va(42);178TestVar vb(std::string("42"));179TestVar vc(43);180181EXPECT_EQ(0u, va.index());182EXPECT_EQ(42, util::get<int>(va));183184EXPECT_EQ(1u, vb.index());185EXPECT_EQ("42", util::get<std::string>(vb));186187EXPECT_EQ(0u, vc.index());188EXPECT_EQ(43, util::get<int>(vc));189190va = std::move(vb);191EXPECT_EQ(1u, va.index());192EXPECT_EQ("42", util::get<std::string>(va));193194va = std::move(vc);195EXPECT_EQ(0u, va.index());196EXPECT_EQ(43, util::get<int>(va));197}198199TEST(Variant, Swap_SameIndex)200{201TestVar tv1(42);202TestVar tv2(43);203204EXPECT_EQ(0u, tv1.index());205EXPECT_EQ(42, util::get<int>(tv1));206207EXPECT_EQ(0u, tv2.index());208EXPECT_EQ(43, util::get<int>(tv2));209210tv1.swap(tv2);211212EXPECT_EQ(0u, tv1.index());213EXPECT_EQ(43, util::get<int>(tv1));214215EXPECT_EQ(0u, tv2.index());216EXPECT_EQ(42, util::get<int>(tv2));217}218219TEST(Variant, Swap_DiffIndex)220{221TestVar2 tv1(42);222TestVar2 tv2(3.14f);223224EXPECT_EQ(0u, tv1.index());225EXPECT_EQ(42, util::get<int>(tv1));226227EXPECT_EQ(1u, tv2.index());228EXPECT_EQ(3.14f, util::get<float>(tv2));229230tv1.swap(tv2);231232EXPECT_EQ(0u, tv2.index());233EXPECT_EQ(42, util::get<int>(tv2));234235EXPECT_EQ(1u, tv1.index());236EXPECT_EQ(3.14f, util::get<float>(tv1));237}238239TEST(Variant, Get)240{241const TestVar cv(42);242243// Test const& get()244EXPECT_EQ(42, util::get<int>(cv));245EXPECT_THROW(util::get<std::string>(cv), util::bad_variant_access);246247// Test &get248TestVar cv2(std::string("42"));249EXPECT_EQ("42", util::get<std::string>(cv2));250EXPECT_THROW(util::get<int>(cv2), util::bad_variant_access);251}252253TEST(Variant, GetWrite)254{255util::variant<int, std::string> v(42);256EXPECT_EQ(42, util::get<int>(v));257258util::get<int>(v) = 43;259EXPECT_EQ(43, util::get<int>(v));260}261262TEST(Variant, NoDefaultCtor)263{264struct MyType265{266int m_a;267MyType() = delete;268};269270// This code MUST compile271util::variant<int, MyType> var;272SUCCEED() << "Code compiled";273274// At the same time, util::variant<MyType, ...> MUST NOT.275}276277TEST(Variant, MonoState)278{279struct MyType280{281int m_a;282explicit MyType(int a) : m_a(a) {}283MyType() = delete;284};285286util::variant<util::monostate, MyType> var;287EXPECT_EQ(0u, var.index());288289var = MyType{42};290EXPECT_EQ(1u, var.index());291EXPECT_EQ(42, util::get<MyType>(var).m_a);292}293294295TEST(Variant, Eq)296{297TestVar v1(42), v2(std::string("42"));298TestVar v3(v1), v4(v2);299300EXPECT_TRUE(v1 == v3);301EXPECT_TRUE(v2 == v4);302EXPECT_TRUE(v1 != v2);303EXPECT_TRUE(v3 != v4);304305EXPECT_FALSE(v1 == v2);306EXPECT_FALSE(v3 == v4);307EXPECT_FALSE(v1 != v3);308EXPECT_FALSE(v2 != v4);309}310311TEST(Variant, Eq_Monostate)312{313using TestVar3 = util::variant<util::monostate, int>;314TestVar3 v1;315TestVar3 v2(42);316317EXPECT_NE(v1, v2);318319v2 = util::monostate{};320EXPECT_EQ(v1, v2);321}322323TEST(Variant, VectorOfVariants)324{325std::vector<TestVar> vv1(1024);326std::vector<TestVar> vv2(1024);327328EXPECT_TRUE(vv1 == vv2);329330std::vector<TestVar> vv3(2048, TestVar(std::string("42")));331332// Just test chat the below code compiles:333// 1: internal copy of variants from one vector to another,334// with probable reallocation of 1st vector to host all elements335std::copy(vv1.begin(), vv1.end(), std::back_inserter(vv2));336EXPECT_EQ(2048u, vv2.size());337338// 2: truncation of vector, with probable destruction of its tail memory339vv2.resize(1024);340EXPECT_EQ(1024u, vv2.size());341342// 3. vector assignment, with overwriting underlying variants343vv2 = vv3;344EXPECT_EQ(2048u, vv2.size());345EXPECT_TRUE(vv2 == vv3);346}347348TEST(Variant, HoldsAlternative)349{350TestVar v(42);351EXPECT_TRUE (util::holds_alternative<int> (v));352EXPECT_FALSE(util::holds_alternative<std::string>(v));353354v = std::string("42");355EXPECT_FALSE(util::holds_alternative<int> (v));356EXPECT_TRUE (util::holds_alternative<std::string>(v));357}358359TEST(Variant, Sizeof)360{361//variant has to store index of the contained type as well as the type itself362EXPECT_EQ(2 * sizeof(size_t), (sizeof(util::variant<int, char>)));363#if !defined(__GNUG__) || __GNUG__ >= 5364// GCC versions prior to 5.0 have limited C++11 support, e.g.365// no std::max_align_t defined366EXPECT_EQ((sizeof(std::max_align_t) + std::max(sizeof(size_t), alignof(std::max_align_t))), (sizeof(util::variant<std::max_align_t, char>)));367#endif368}369370TEST(Variant, EXT_IndexOf)371{372struct MyType{};373class MyClass{};374375using V = util::variant<util::monostate, int, double, char, float, MyType, MyClass>;376static_assert(0u == V::index_of<util::monostate>(), "Index is incorrect");377static_assert(1u == V::index_of<int >(), "Index is incorrect");378static_assert(2u == V::index_of<double >(), "Index is incorrect");379static_assert(3u == V::index_of<char >(), "Index is incorrect");380static_assert(4u == V::index_of<float >(), "Index is incorrect");381static_assert(5u == V::index_of<MyType >(), "Index is incorrect");382static_assert(6u == V::index_of<MyClass>(), "Index is incorrect");383}384385} // namespace opencv_test386387388