// Copyright (C) 2009 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <dlib/type_safe_union.h>
#include "tester.h"
namespace
{
using namespace test;
using namespace dlib;
using namespace std;
logger dlog("test.type_safe_union");
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<float, double, char, std::string>;
typedef type_safe_union<float, double, char, std::string> 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<char>() == false);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(a.contains<double>() == false);
DLIB_TEST(a.contains<std::string>() == false);
DLIB_TEST(a.contains<long>() == false);
DLIB_TEST(a.get_type_id<int>() == -1);
DLIB_TEST(a.get_type_id<float>() == 1);
DLIB_TEST(a.get_type_id<double>() == 2);
DLIB_TEST(a.get_type_id<char>() == 3);
DLIB_TEST(a.get_type_id<std::string>() == 4);
DLIB_TEST(a.get_type_id<tsu>() == -1);
f_val = 4.345f;
a.get<float>() = f_val;
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == false);
DLIB_TEST(a.contains<float>() == true);
DLIB_TEST(a.contains<double>() == false);
DLIB_TEST(a.contains<std::string>() == false);
DLIB_TEST(a.contains<long>() == false);
last_kind = NONE;
const_cast<const tsu&>(a).apply_to_contents(*this);
DLIB_TEST(last_kind == FLOAT);
// -----------
d_val = 4.345;
a.get<double>() = d_val;
last_kind = NONE;
a.apply_to_contents(*this);
DLIB_TEST(last_kind == DOUBLE);
// -----------
c_val = 'a';
a.get<char>() = c_val;
last_kind = NONE;
const_cast<const tsu&>(a).apply_to_contents(*this);
DLIB_TEST(last_kind == CHAR);
// -----------
s_val = "test string";
a.get<std::string>() = s_val;
last_kind = NONE;
a.apply_to_contents(*this);
DLIB_TEST(last_kind == STRING);
// -----------
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == false);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(a.contains<double>() == false);
DLIB_TEST(a.contains<std::string>() == true);
DLIB_TEST(a.contains<long>() == false);
// -----------
a.swap(b);
DLIB_TEST(a.is_empty() == true);
DLIB_TEST(a.contains<char>() == false);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(a.contains<double>() == false);
DLIB_TEST(a.contains<std::string>() == false);
DLIB_TEST(a.contains<long>() == false);
DLIB_TEST(b.is_empty() == false);
DLIB_TEST(b.contains<char>() == false);
DLIB_TEST(b.contains<float>() == false);
DLIB_TEST(b.contains<double>() == false);
DLIB_TEST(b.contains<std::string>() == true);
DLIB_TEST(b.contains<long>() == 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<char>() == false);
DLIB_TEST(b.contains<float>() == false);
DLIB_TEST(b.contains<double>() == false);
DLIB_TEST(b.contains<std::string>() == false);
DLIB_TEST(b.contains<long>() == false);
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == false);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(a.contains<double>() == false);
DLIB_TEST(a.contains<std::string>() == true);
DLIB_TEST(a.contains<long>() == 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<char>() = 'a';
b.get<char>() = 'b';
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == true);
DLIB_TEST(b.is_empty() == false);
DLIB_TEST(b.contains<char>() == true);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(b.contains<float>() == false);
DLIB_TEST(a.get<char>() == 'a');
DLIB_TEST(b.get<char>() == 'b');
swap(a,b);
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == true);
DLIB_TEST(b.is_empty() == false);
DLIB_TEST(b.contains<char>() == true);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(b.contains<float>() == false);
DLIB_TEST(a.get<char>() == 'b');
DLIB_TEST(b.get<char>() == 'a');
// -----------
a.get<char>() = 'a';
b.get<std::string>() = "a string";
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == true);
DLIB_TEST(b.is_empty() == false);
DLIB_TEST(b.contains<char>() == false);
DLIB_TEST(a.contains<std::string>() == false);
DLIB_TEST(b.contains<std::string>() == true);
DLIB_TEST(a.get<char>() == 'a');
DLIB_TEST(b.get<std::string>() == "a string");
swap(a,b);
DLIB_TEST(b.is_empty() == false);
DLIB_TEST(b.contains<char>() == true);
DLIB_TEST(a.is_empty() == false);
DLIB_TEST(a.contains<char>() == false);
DLIB_TEST(b.contains<std::string>() == false);
DLIB_TEST(a.contains<std::string>() == true);
DLIB_TEST(b.get<char>() == 'a');
DLIB_TEST(a.get<std::string>() == "a string");
{
type_safe_union<char, float, std::string> a, b, empty_union;
ostringstream sout;
istringstream sin;
a.get<char>() = 'd';
serialize(a, sout);
sin.str(sout.str());
deserialize(b, sin);
DLIB_TEST(b.contains<int>() == false);
DLIB_TEST(b.contains<float>() == false);
DLIB_TEST(b.contains<char>() == true);
DLIB_TEST(b.get<char>() == 'd');
DLIB_TEST(a.contains<int>() == false);
DLIB_TEST(a.contains<float>() == false);
DLIB_TEST(a.contains<char>() == true);
DLIB_TEST(a.get<char>() == 'd');
sin.clear();
sout.clear();
sout.str("");
a.get<std::string>() = "davis";
serialize(a, sout);
sin.str(sout.str());
deserialize(b, sin);
DLIB_TEST(b.contains<int>() == false);
DLIB_TEST(b.contains<float>() == false);
DLIB_TEST(b.contains<std::string>() == true);
DLIB_TEST(b.get<std::string>() == "davis");
sin.clear();
sout.clear();
sout.str("");
serialize(empty_union, sout);
sin.str(sout.str());
deserialize(b, sin);
DLIB_TEST(b.is_empty() == 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;
}