// Copyright (C) 2009 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #include #include #include #include #include #include "tester.h" namespace { using namespace test; using namespace dlib; using namespace std; logger dlog("test.type_safe_union"); struct can_not_copy: noncopyable {}; void serialize(const can_not_copy&, std::ostream&) {} void deserialize(can_not_copy&, std::istream&) {} void swap(can_not_copy&, can_not_copy&) {} class test { private: enum kind { FLOAT, DOUBLE, CHAR, STRING, NONE }; void operator() (float val) { DLIB_TEST(val == f_val); last_kind = FLOAT; } void operator() (double val) { DLIB_TEST(val == d_val); last_kind = DOUBLE; } void operator() (char val) { DLIB_TEST(val == c_val); last_kind = CHAR; } void operator()(std::string& val) { DLIB_TEST(val == s_val); last_kind = STRING; } void operator()(const std::string& val) { DLIB_TEST(val == s_val); last_kind = STRING; } // ------------------------------ friend class type_safe_union; typedef type_safe_union tsu; tsu a, b, c; float f_val; double d_val; char c_val; std::string s_val; kind last_kind; public: void test_stuff() { DLIB_TEST(a.is_empty() == true); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.get_type_id() == -1); DLIB_TEST(a.get_type_id() == 1); DLIB_TEST(a.get_type_id() == 2); DLIB_TEST(a.get_type_id() == 3); DLIB_TEST(a.get_type_id() == 4); DLIB_TEST(a.get_type_id() == -1); f_val = 4.345f; a.get() = f_val; DLIB_TEST(a.cast_to() == f_val); DLIB_TEST(const_cast(a).cast_to() == f_val); bool exception_thrown = false; try {a.cast_to(); } catch (bad_type_safe_union_cast&) { exception_thrown = true;} DLIB_TEST(exception_thrown); DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); last_kind = NONE; const_cast(a).apply_to_contents(*this); DLIB_TEST(last_kind == FLOAT); // ----------- d_val = 4.345; a.get() = d_val; last_kind = NONE; a.apply_to_contents(*this); DLIB_TEST(last_kind == DOUBLE); // ----------- c_val = 'a'; a.get() = c_val; last_kind = NONE; const_cast(a).apply_to_contents(*this); DLIB_TEST(last_kind == CHAR); // ----------- s_val = "test string"; a.get() = s_val; last_kind = NONE; a.apply_to_contents(*this); DLIB_TEST(last_kind == STRING); DLIB_TEST(a.cast_to() == s_val); exception_thrown = false; try {a.cast_to(); } catch (bad_type_safe_union_cast&) { exception_thrown = true;} DLIB_TEST(exception_thrown); // ----------- DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(a.contains() == false); // ----------- a.swap(b); DLIB_TEST(a.is_empty() == true); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(b.is_empty() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.contains() == false); last_kind = NONE; b.apply_to_contents(*this); DLIB_TEST(last_kind == STRING); // ----------- b.swap(a); DLIB_TEST(b.is_empty() == true); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(a.contains() == false); last_kind = NONE; a.apply_to_contents(*this); DLIB_TEST(last_kind == STRING); last_kind = NONE; b.apply_to_contents(*this); DLIB_TEST(last_kind == NONE); a.get() = 'a'; b.get() = 'b'; DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(b.is_empty() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(a.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(a.get() == 'a'); DLIB_TEST(b.get() == 'b'); swap(a,b); DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(b.is_empty() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(a.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(a.get() == 'b'); DLIB_TEST(b.get() == 'a'); // ----------- a.get() = 'a'; b.get() = "a string"; DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(b.is_empty() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(a.get() == 'a'); DLIB_TEST(b.get() == "a string"); swap(a,b); DLIB_TEST(b.is_empty() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(a.is_empty() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(b.get() == 'a'); DLIB_TEST(a.get() == "a string"); { type_safe_union a, b, empty_union; ostringstream sout; istringstream sin; a.get() = 'd'; serialize(a, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.get() == 'd'); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(a.get() == 'd'); sin.clear(); sout.clear(); sout.str(""); a.get() = "davis"; serialize(a, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.get() == "davis"); sin.clear(); sout.clear(); sout.str(""); serialize(empty_union, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.is_empty() == true); } { type_safe_union a, b, empty_union; ostringstream sout; istringstream sin; a = 'd'; serialize(a, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.get() == 'd'); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(a.get() == 'd'); sin.clear(); sout.clear(); sout.str(""); a = std::string("davis"); serialize(a, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.get() == "davis"); sin.clear(); sout.clear(); sout.str(""); serialize(empty_union, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.is_empty() == true); } { typedef type_safe_union tsu_type; tsu_type a('d'), aa(std::string("davis")), b, empty_union; ostringstream sout; istringstream sin; serialize(a, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.get() == 'd'); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == false); DLIB_TEST(a.contains() == true); DLIB_TEST(a.get() == 'd'); DLIB_TEST(aa.contains() == false); DLIB_TEST(aa.contains() == false); DLIB_TEST(aa.contains() == false); DLIB_TEST(aa.contains() == true); sin.clear(); sout.clear(); sout.str(""); serialize(aa, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == false); DLIB_TEST(b.contains() == true); DLIB_TEST(b.get() == "davis"); sin.clear(); sout.clear(); sout.str(""); serialize(empty_union, sout); sin.str(sout.str()); deserialize(b, sin); DLIB_TEST(b.is_empty() == true); a.get(); DLIB_TEST(a.contains() == true); } } }; class type_safe_union_tester : public tester { public: type_safe_union_tester ( ) : tester ("test_type_safe_union", "Runs tests on the type_safe_union object") {} void perform_test ( ) { for (int i = 0; i < 10; ++i) { test a; a.test_stuff(); } } } a; }