125 lines
5.0 KiB
C
125 lines
5.0 KiB
C
|
// File: crn_traits.h
|
||
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
||
|
#pragma once
|
||
|
|
||
|
namespace crnlib
|
||
|
{
|
||
|
template<typename T> struct int_traits { enum { cMin = crnlib::cINT32_MIN, cMax = crnlib::cINT32_MAX, cSigned = true }; };
|
||
|
|
||
|
template<> struct int_traits<int8> { enum { cMin = crnlib::cINT8_MIN, cMax = crnlib::cINT8_MAX, cSigned = true }; };
|
||
|
template<> struct int_traits<int16> { enum { cMin = crnlib::cINT16_MIN, cMax = crnlib::cINT16_MAX, cSigned = true }; };
|
||
|
template<> struct int_traits<int32> { enum { cMin = crnlib::cINT32_MIN, cMax = crnlib::cINT32_MAX, cSigned = true }; };
|
||
|
|
||
|
template<> struct int_traits<uint8> { enum { cMin = 0, cMax = crnlib::cUINT8_MAX, cSigned = false }; };
|
||
|
template<> struct int_traits<uint16> { enum { cMin = 0, cMax = crnlib::cUINT16_MAX, cSigned = false }; };
|
||
|
template<> struct int_traits<uint32> { enum { cMin = 0, cMax = crnlib::cUINT32_MAX, cSigned = false }; };
|
||
|
template<typename T>
|
||
|
struct scalar_type
|
||
|
{
|
||
|
enum { cFlag = false };
|
||
|
static inline void construct(T* p) { helpers::construct(p); }
|
||
|
static inline void construct(T* p, const T& init) { helpers::construct(p, init); }
|
||
|
static inline void construct_array(T* p, uint n) { helpers::construct_array(p, n); }
|
||
|
static inline void destruct(T* p) { helpers::destruct(p); }
|
||
|
static inline void destruct_array(T* p, uint n) { helpers::destruct_array(p, n); }
|
||
|
};
|
||
|
|
||
|
template<typename T> struct scalar_type<T*>
|
||
|
{
|
||
|
enum { cFlag = true };
|
||
|
static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
|
||
|
static inline void construct(T** p, T* init) { *p = init; }
|
||
|
static inline void construct_array(T** p, uint n) { memset(p, 0, sizeof(T*) * n); }
|
||
|
static inline void destruct(T** p) { p; }
|
||
|
static inline void destruct_array(T** p, uint n) { p, n; }
|
||
|
};
|
||
|
|
||
|
#define CRNLIB_DEFINE_BUILT_IN_TYPE(X) \
|
||
|
template<> struct scalar_type<X> { \
|
||
|
enum { cFlag = true }; \
|
||
|
static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
|
||
|
static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
|
||
|
static inline void construct_array(X* p, uint n) { memset(p, 0, sizeof(X) * n); } \
|
||
|
static inline void destruct(X* p) { p; } \
|
||
|
static inline void destruct_array(X* p, uint n) { p, n; } };
|
||
|
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(bool)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(char)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned char)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(short)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned short)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(int)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned int)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(long)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned long)
|
||
|
#ifdef __GNUC__
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(long long)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned long long)
|
||
|
#else
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(__int64)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned __int64)
|
||
|
#endif
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(float)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(double)
|
||
|
CRNLIB_DEFINE_BUILT_IN_TYPE(long double)
|
||
|
|
||
|
#undef CRNLIB_DEFINE_BUILT_IN_TYPE
|
||
|
|
||
|
// See: http://erdani.org/publications/cuj-2004-06.pdf
|
||
|
|
||
|
template<typename T>
|
||
|
struct bitwise_movable { enum { cFlag = false }; };
|
||
|
|
||
|
// Defines type Q as bitwise movable.
|
||
|
// Bitwise movable: type T may be safely moved to a new location via memcpy, without requiring the old copy to be destructed.
|
||
|
// However, the final version of the object (wherever it winds up in memory) must be eventually destructed (a single time, of course).
|
||
|
// Bitwise movable is a superset of bitwise copyable (all bitwise copyable types are also bitwise movable).
|
||
|
#define CRNLIB_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable<Q> { enum { cFlag = true }; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct bitwise_copyable { enum { cFlag = false }; };
|
||
|
|
||
|
// Defines type Q as bitwise copyable.
|
||
|
// Bitwise copyable: type T may be safely and freely copied (duplicated) via memcpy, and *does not* require destruction.
|
||
|
#define CRNLIB_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable<Q> { enum { cFlag = true }; };
|
||
|
|
||
|
#define CRNLIB_IS_POD(T) __is_pod(T)
|
||
|
|
||
|
#define CRNLIB_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)
|
||
|
|
||
|
#define CRNLIB_IS_BITWISE_COPYABLE(T) (CRNLIB_IS_SCALAR_TYPE(T) || CRNLIB_IS_POD(T) || (bitwise_copyable<T>::cFlag))
|
||
|
|
||
|
#define CRNLIB_IS_BITWISE_COPYABLE_OR_MOVABLE(T) (CRNLIB_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))
|
||
|
|
||
|
#define CRNLIB_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!__is_pod(T)))
|
||
|
|
||
|
// From yasli_traits.h:
|
||
|
// Credit goes to Boost;
|
||
|
// also found in the C++ Templates book by Vandevoorde and Josuttis
|
||
|
|
||
|
typedef char (&yes_t)[1];
|
||
|
typedef char (&no_t)[2];
|
||
|
|
||
|
template <class U> yes_t class_test(int U::*);
|
||
|
template <class U> no_t class_test(...);
|
||
|
|
||
|
template <class T> struct is_class
|
||
|
{
|
||
|
enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) };
|
||
|
};
|
||
|
|
||
|
template <typename T> struct is_pointer
|
||
|
{
|
||
|
enum { value = false };
|
||
|
};
|
||
|
|
||
|
template <typename T> struct is_pointer<T*>
|
||
|
{
|
||
|
enum { value = true };
|
||
|
};
|
||
|
|
||
|
CRNLIB_DEFINE_BITWISE_COPYABLE(empty_type);
|
||
|
CRNLIB_DEFINE_BITWISE_MOVABLE(empty_type);
|
||
|
|
||
|
} // namespace crnlib
|