Commit d9fb6199 authored by Davis King's avatar Davis King

Added serialization support to the type_safe_union object.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403022
parent 8c239d0a
...@@ -231,6 +231,57 @@ namespace ...@@ -231,6 +231,57 @@ namespace
{
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);
}
} }
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "type_safe_union_kernel_abstract.h" #include "type_safe_union_kernel_abstract.h"
#include "../algs.h" #include "../algs.h"
#include "../noncopyable.h" #include "../noncopyable.h"
#include "../serialize.h"
#include <new> #include <new>
namespace dlib namespace dlib
...@@ -158,6 +159,75 @@ namespace dlib ...@@ -158,6 +159,75 @@ namespace dlib
return type_identity == 0; return type_identity == 0;
} }
private:
struct serialize_helper
{
/*
This is a function object to help us serialize type_safe_unions
*/
std::ostream& out;
serialize_helper(std::ostream& out_): out(out_) {}
template <typename T>
void operator() (const T& item) const { serialize(item, out); }
};
public:
friend void serialize (
const type_safe_union& item,
std::ostream& out
)
{
try
{
// save the type_identity
serialize(item.type_identity, out);
// Now save whatever it is item contains. Note that the const cast is ok
// here since serialize_helper doesn't modify anything in item.
const_cast<type_safe_union&>(item).apply_to_contents(serialize_helper(out));
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while serializing an object of type type_safe_union");
}
}
friend void deserialize (
type_safe_union& item,
std::istream& in
)
{
try
{
int type_identity;
deserialize(type_identity, in);
switch (type_identity)
{
// swap an empty type_safe_union into item since it should be in the empty state
case 0: type_safe_union().swap(item); break;
case 1: deserialize(item.get<T1>(), in); break;
case 2: deserialize(item.get<T2>(), in); break;
case 3: deserialize(item.get<T3>(), in); break;
case 4: deserialize(item.get<T4>(), in); break;
case 5: deserialize(item.get<T5>(), in); break;
case 6: deserialize(item.get<T6>(), in); break;
case 7: deserialize(item.get<T7>(), in); break;
case 8: deserialize(item.get<T8>(), in); break;
case 9: deserialize(item.get<T9>(), in); break;
case 10: deserialize(item.get<T10>(), in); break;
default: throw serialization_error("Corrupt data detected while deserializing type_safe_union");
}
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while deserializing an object of type type_safe_union");
}
}
template < template <
typename T typename T
> >
......
...@@ -157,6 +157,32 @@ namespace dlib ...@@ -157,6 +157,32 @@ namespace dlib
provides a global swap function provides a global swap function
!*/ !*/
// ----------------------------------------------------------------------------------------
template <
typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10
>
void serialize (
const type_safe_union<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>& item,
std::istream& in
);
/*!
provides serialization support
!*/
template <
typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10
>
void deserialize (
type_safe_union<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>& item,
std::istream& in
);
/*!
provides deserialization support
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment