// File: crn_traits.h // See Copyright Notice and license at the end of inc/crnlib.h #pragma once namespace crnlib { template struct int_traits { enum { cMin = crnlib::cINT32_MIN, cMax = crnlib::cINT32_MAX, cSigned = true }; }; template<> struct int_traits { enum { cMin = crnlib::cINT8_MIN, cMax = crnlib::cINT8_MAX, cSigned = true }; }; template<> struct int_traits { enum { cMin = crnlib::cINT16_MIN, cMax = crnlib::cINT16_MAX, cSigned = true }; }; template<> struct int_traits { enum { cMin = crnlib::cINT32_MIN, cMax = crnlib::cINT32_MAX, cSigned = true }; }; template<> struct int_traits { enum { cMin = 0, cMax = crnlib::cUINT8_MAX, cSigned = false }; }; template<> struct int_traits { enum { cMin = 0, cMax = crnlib::cUINT16_MAX, cSigned = false }; }; template<> struct int_traits { enum { cMin = 0, cMax = crnlib::cUINT32_MAX, cSigned = false }; }; template 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 struct scalar_type { 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 { \ 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 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 { enum { cFlag = true }; }; template 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 { enum { cFlag = true }; }; #define CRNLIB_IS_POD(T) __is_pod(T) #define CRNLIB_IS_SCALAR_TYPE(T) (scalar_type::cFlag) #define CRNLIB_IS_BITWISE_COPYABLE(T) (CRNLIB_IS_SCALAR_TYPE(T) || CRNLIB_IS_POD(T) || (bitwise_copyable::cFlag)) #define CRNLIB_IS_BITWISE_COPYABLE_OR_MOVABLE(T) (CRNLIB_IS_BITWISE_COPYABLE(T) || (bitwise_movable::cFlag)) #define CRNLIB_HAS_DESTRUCTOR(T) ((!scalar_type::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 yes_t class_test(int U::*); template no_t class_test(...); template struct is_class { enum { value = (sizeof(class_test(0)) == sizeof(yes_t)) }; }; template struct is_pointer { enum { value = false }; }; template struct is_pointer { enum { value = true }; }; CRNLIB_DEFINE_BITWISE_COPYABLE(empty_type); CRNLIB_DEFINE_BITWISE_MOVABLE(empty_type); } // namespace crnlib