p2p/stingray_sdk/plugin_foundation/template_tools.h
Lucas Schwiderski 2c9ce46dd2
chore: Rework project structure
There likely won't be much need for multiple separate crates.
2023-05-26 23:42:01 +02:00

51 lines
1.3 KiB
C++

#pragma once
#include "assert.h"
namespace stingray_plugin_foundation {
// Convert integer to type.
template <int v>
struct Int2Type { enum {value=v}; };
// Determines if a class is allocator aware.
template <class T>
struct is_allocator_aware {
template <typename C>
static char test_fun(typename C::allocator_aware *);
template <typename C>
static int test_fun(...);
public:
enum {
value = (sizeof(test_fun<T>(0)) == sizeof(char))
};
};
#define IS_ALLOCATOR_AWARE(T) is_allocator_aware<T>::value
#define IS_ALLOCATOR_AWARE_TYPE(T) Int2Type< IS_ALLOCATOR_AWARE(T) >
// Allocator aware constuction
template <class T> inline T &construct(void *p, Allocator &a, Int2Type<true>) {new (p) T(a); return *(T *)p;}
template <class T> inline T &construct(void *p, Allocator &a, Int2Type<false>) {new (p) T; return *(T *)p;}
template <class T> inline T &construct(void *p, Allocator &a) {return construct<T>(p, a, IS_ALLOCATOR_AWARE_TYPE(T)());}
// Helper for casts using a union. This circumvents the aliasing problem that occurs when
// trying to reinterpret a float as int and vice versa for example.
template<typename A, typename B>
A safe_reinterpret_cast(const B &b) {
static_assert(sizeof(A) == sizeof(B), "Types must have same size to be cast");
union U {
A a;
B b;
} u;
u.b = b;
return u.a;
}
}