mirror of https://github.com/davisking/dlib.git
[TYPE_SAFE_UNION] use std::aligned_union instead of stack_based_memory_block (#2349)
* [TYPE_SAFE_UNION] use std::aligned_union instead of stack_based_memory_block. std::aligned_union was specifically designed to do this kind of stuff and we are better off trusting the standard library deciding what the correct storage type should be and what the appropriate alignment should be * [TYPE_SAFE_UNION] as per Davis' suggestion, std::aligned_union can take Len parameter 0. Also, the content's of validate_type() has been bugging me for ages, so i created is_any which is based on std::is_same. I've also replaced is_same_type with std::is_same Co-authored-by: Peter Featherstone <peter@grampus-server.com>
This commit is contained in:
parent
8d4df7c0b3
commit
d6d1a9e879
17
dlib/algs.h
17
dlib/algs.h
|
@ -480,6 +480,23 @@ namespace dlib
|
|||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*!A is_any
|
||||
|
||||
This is a template where is_any<T,Rest...>::value == true when T is
|
||||
the same type as any one of the types in Rest...
|
||||
!*/
|
||||
|
||||
template <typename T, typename... Rest>
|
||||
struct is_any : std::false_type {};
|
||||
|
||||
template <typename T, typename First>
|
||||
struct is_any<T,First> : std::is_same<T,First> {};
|
||||
|
||||
template <typename T, typename First, typename... Rest>
|
||||
struct is_any<T,First,Rest...> : std::integral_constant<bool, std::is_same<T,First>::value || is_any<T,Rest...>::value> {};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*!A is_float_type
|
||||
|
||||
This is a template that can be used to determine if a type is one of the built
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace dlib
|
|||
CONVENTION
|
||||
- is_empty() == (type_identity == 0)
|
||||
- contains<T>() == (type_identity == get_type_id<T>())
|
||||
- mem.get() == the block of memory on the stack which is
|
||||
- mem == the aligned block of memory on the stack which is
|
||||
where objects in the union are stored
|
||||
!*/
|
||||
|
||||
|
@ -85,33 +85,11 @@ namespace dlib
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
const static size_t max_size = tmax<tmax<tmax<tmax<tmax<tmax<tmax<tmax<tmax<tmax<
|
||||
tmax<tmax<tmax<tmax<tmax<tmax<tmax<tmax<tmax<sizeof(T1),
|
||||
sizeof(T2)>::value,
|
||||
sizeof(T3)>::value,
|
||||
sizeof(T4)>::value,
|
||||
sizeof(T5)>::value,
|
||||
sizeof(T6)>::value,
|
||||
sizeof(T7)>::value,
|
||||
sizeof(T8)>::value,
|
||||
sizeof(T9)>::value,
|
||||
sizeof(T10)>::value,
|
||||
sizeof(T11)>::value,
|
||||
sizeof(T12)>::value,
|
||||
sizeof(T13)>::value,
|
||||
sizeof(T14)>::value,
|
||||
sizeof(T15)>::value,
|
||||
sizeof(T16)>::value,
|
||||
sizeof(T17)>::value,
|
||||
sizeof(T18)>::value,
|
||||
sizeof(T19)>::value,
|
||||
sizeof(T20)>::value;
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
// member data
|
||||
stack_based_memory_block<max_size> mem;
|
||||
typename std::aligned_union<0, T1,T2,T3,T4,T5,
|
||||
T6,T7,T8,T9,T10,
|
||||
T11,T12,T13,T14,T15,
|
||||
T16,T17,T18,T19,T20>::type mem;
|
||||
int type_identity;
|
||||
|
||||
// --------------------------------------------
|
||||
|
@ -120,32 +98,11 @@ namespace dlib
|
|||
void validate_type() const
|
||||
{
|
||||
// ERROR: You are trying to get a type of object that isn't
|
||||
// representable by this type_safe_union. I.e. The given
|
||||
// type T isn't one of the ones given to this object's template
|
||||
// arguments.
|
||||
COMPILE_TIME_ASSERT(( is_same_type<T,T1>::value ||
|
||||
is_same_type<T,T2>::value ||
|
||||
is_same_type<T,T3>::value ||
|
||||
is_same_type<T,T4>::value ||
|
||||
is_same_type<T,T5>::value ||
|
||||
is_same_type<T,T6>::value ||
|
||||
is_same_type<T,T7>::value ||
|
||||
is_same_type<T,T8>::value ||
|
||||
is_same_type<T,T9>::value ||
|
||||
is_same_type<T,T10>::value ||
|
||||
|
||||
is_same_type<T,T11>::value ||
|
||||
is_same_type<T,T12>::value ||
|
||||
is_same_type<T,T13>::value ||
|
||||
is_same_type<T,T14>::value ||
|
||||
is_same_type<T,T15>::value ||
|
||||
is_same_type<T,T16>::value ||
|
||||
is_same_type<T,T17>::value ||
|
||||
is_same_type<T,T18>::value ||
|
||||
is_same_type<T,T19>::value ||
|
||||
is_same_type<T,T20>::value
|
||||
));
|
||||
|
||||
// representable by this type_safe_union.
|
||||
static_assert(is_any<T,T1,T2,T3,T4,T5,
|
||||
T6,T7,T8,T9,T10,
|
||||
T11,T12,T13,T14,T15,
|
||||
T16,T17,T18,T19,T20>::value, "Type T isn't one of the ones given to this object's template arguments.");
|
||||
}
|
||||
|
||||
|
||||
|
@ -179,7 +136,7 @@ namespace dlib
|
|||
if (type_identity != get_type_id<T>())
|
||||
{
|
||||
destruct();
|
||||
new(mem.get()) T();
|
||||
new(&mem) T();
|
||||
type_identity = get_type_id<T>();
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +150,7 @@ namespace dlib
|
|||
if (type_identity != get_type_id<U>())
|
||||
{
|
||||
destruct();
|
||||
new(mem.get()) U(std::forward<T>(item));
|
||||
new(&mem) U(std::forward<T>(item));
|
||||
type_identity = get_type_id<U>();
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +165,7 @@ namespace dlib
|
|||
- returns a non-const reference to the T object
|
||||
!*/
|
||||
{
|
||||
return *static_cast<T*>(mem.get());
|
||||
return *reinterpret_cast<T*>(&mem);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -221,7 +178,7 @@ namespace dlib
|
|||
- returns a const reference to the T object
|
||||
!*/
|
||||
{
|
||||
return *static_cast<const T*>(mem.get());
|
||||
return *reinterpret_cast<const T*>(&mem);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -287,29 +244,29 @@ namespace dlib
|
|||
static int get_type_id (
|
||||
)
|
||||
{
|
||||
if (is_same_type<T,T1>::value) return 1;
|
||||
if (is_same_type<T,T2>::value) return 2;
|
||||
if (is_same_type<T,T3>::value) return 3;
|
||||
if (is_same_type<T,T4>::value) return 4;
|
||||
if (is_same_type<T,T5>::value) return 5;
|
||||
if (std::is_same<T,T1>::value) return 1;
|
||||
if (std::is_same<T,T2>::value) return 2;
|
||||
if (std::is_same<T,T3>::value) return 3;
|
||||
if (std::is_same<T,T4>::value) return 4;
|
||||
if (std::is_same<T,T5>::value) return 5;
|
||||
|
||||
if (is_same_type<T,T6>::value) return 6;
|
||||
if (is_same_type<T,T7>::value) return 7;
|
||||
if (is_same_type<T,T8>::value) return 8;
|
||||
if (is_same_type<T,T9>::value) return 9;
|
||||
if (is_same_type<T,T10>::value) return 10;
|
||||
if (std::is_same<T,T6>::value) return 6;
|
||||
if (std::is_same<T,T7>::value) return 7;
|
||||
if (std::is_same<T,T8>::value) return 8;
|
||||
if (std::is_same<T,T9>::value) return 9;
|
||||
if (std::is_same<T,T10>::value) return 10;
|
||||
|
||||
if (is_same_type<T,T11>::value) return 11;
|
||||
if (is_same_type<T,T12>::value) return 12;
|
||||
if (is_same_type<T,T13>::value) return 13;
|
||||
if (is_same_type<T,T14>::value) return 14;
|
||||
if (is_same_type<T,T15>::value) return 15;
|
||||
if (std::is_same<T,T11>::value) return 11;
|
||||
if (std::is_same<T,T12>::value) return 12;
|
||||
if (std::is_same<T,T13>::value) return 13;
|
||||
if (std::is_same<T,T14>::value) return 14;
|
||||
if (std::is_same<T,T15>::value) return 15;
|
||||
|
||||
if (is_same_type<T,T16>::value) return 16;
|
||||
if (is_same_type<T,T17>::value) return 17;
|
||||
if (is_same_type<T,T18>::value) return 18;
|
||||
if (is_same_type<T,T19>::value) return 19;
|
||||
if (is_same_type<T,T20>::value) return 20;
|
||||
if (std::is_same<T,T16>::value) return 16;
|
||||
if (std::is_same<T,T17>::value) return 17;
|
||||
if (std::is_same<T,T18>::value) return 18;
|
||||
if (std::is_same<T,T19>::value) return 19;
|
||||
if (std::is_same<T,T20>::value) return 20;
|
||||
|
||||
// return a number that doesn't match any of the
|
||||
// valid states of type_identity
|
||||
|
@ -538,7 +495,7 @@ namespace dlib
|
|||
{
|
||||
validate_type<T>();
|
||||
construct<T>();
|
||||
return *static_cast<T*>(mem.get());
|
||||
return *reinterpret_cast<T*>(&mem);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -547,7 +504,7 @@ namespace dlib
|
|||
{
|
||||
validate_type<T>();
|
||||
if (contains<T>())
|
||||
return *static_cast<const T*>(mem.get());
|
||||
return *reinterpret_cast<const T*>(&mem);
|
||||
else
|
||||
throw bad_type_safe_union_cast();
|
||||
}
|
||||
|
@ -558,7 +515,7 @@ namespace dlib
|
|||
{
|
||||
validate_type<T>();
|
||||
if (contains<T>())
|
||||
return *static_cast<T*>(mem.get());
|
||||
return *reinterpret_cast<T*>(&mem);
|
||||
else
|
||||
throw bad_type_safe_union_cast();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue