"vscode:/vscode.git/clone" did not exist on "2f5000e3daacb7a97dc4c6b8279b748717190ca8"
Commit 5bcbe617 authored by Davis King's avatar Davis King
Browse files

make type_safe_union movable and also support holding movable types in a natural way.

parent afe19fcb
......@@ -422,6 +422,42 @@ namespace
DLIB_TEST(a.contains<can_not_copy>() == true);
}
{
type_safe_union<int,std::string> a, b;
a = std::string("asdf");
b = 3;
b = std::move(a);
DLIB_TEST(a.get<int>() == 3);
DLIB_TEST(b.get<std::string>() == "asdf");
}
{
type_safe_union<int,std::string> a = 3;
type_safe_union<int,std::string> b = std::string("asdf");
DLIB_TEST(a.get<int>() == 3);
DLIB_TEST(b.get<std::string>() == "asdf");
}
{
using ptr_t = std::unique_ptr<std::string>;
type_safe_union<int, ptr_t> a;
type_safe_union<int, ptr_t> b = ptr_t(new std::string("asdf"));
a = std::move(b);
DLIB_TEST(a.contains<ptr_t>());
DLIB_TEST(!b.contains<ptr_t>());
DLIB_TEST(*a.get<ptr_t>() == "asdf");
swap(a,b);
DLIB_TEST(b.contains<ptr_t>());
DLIB_TEST(!a.contains<ptr_t>());
DLIB_TEST(*b.get<ptr_t>() == "asdf");
}
}
};
......
......@@ -9,6 +9,7 @@
#include "../serialize.h"
#include <new>
#include <iostream>
#include <type_traits>
namespace dlib
{
......@@ -185,14 +186,15 @@ namespace dlib
template <typename T>
void construct (
const T& item
T&& item
)
{
if (type_identity != get_type_id<T>())
using U = typename std::decay<T>::type;
if (type_identity != get_type_id<U>())
{
destruct();
new(mem.get()) T(item);
type_identity = get_type_id<T>();
new(mem.get()) U(std::forward<T>(item));
type_identity = get_type_id<U>();
}
}
......@@ -262,11 +264,18 @@ namespace dlib
template <typename T>
type_safe_union (
const T& item
T&& item
) : type_identity(0)
{
validate_type<T>();
construct(item);
validate_type<typename std::decay<T>::type>();
construct(std::forward<T>(item));
}
type_safe_union (
type_safe_union&& item
) : type_safe_union()
{
swap(item);
}
~type_safe_union()
......@@ -555,7 +564,9 @@ namespace dlib
}
template <typename T>
type_safe_union& operator= ( const T& item) { get<T>() = item; return *this; }
type_safe_union& operator= (T&& item) { get<typename std::decay<T>::type>() = std::forward<T>(item); return *this; }
type_safe_union& operator= (type_safe_union&& item) { swap(item); return *this; }
};
......
......@@ -101,7 +101,7 @@ namespace dlib
template <typename T>
type_safe_union (
const T& item
T&& item
);
/*!
requires
......@@ -109,7 +109,15 @@ namespace dlib
ensures
- this object is properly initialized
- #get<T>() == item
(i.e. this object will contain a copy of item)
(i.e. this object will contain a copy of item, or we move item if it's an rvalue)
!*/
type_safe_union (
type_safe_union&& item
);
/*!
ensures
- move constructs *this from item.
!*/
~type_safe_union(
......@@ -262,14 +270,23 @@ namespace dlib
template <typename T>
type_safe_union& operator= (
const T& item
T&& item
);
/*!
requires
- T must be one of the types given to this object's template arguments
ensures
- #get<T>() == item
(i.e. this object will contain a copy of item)
(i.e. this object will contain a copy of item, or we move item if it's an rvalue)
- returns *this
!*/
type_safe_union& operator= (
type_safe_union&& item
);
/*!
ensures
- Allows moving item into *this. In fact, this is done by this->swap(item).
- returns *this
!*/
......
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