From f9cc4926f27a9294a5e83d9ddc11497b0cd7c65f Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 25 May 2012 15:19:07 +1000 Subject: [PATCH] Categorise functionality from types.hpp --- Makefile.am | 7 +- endian.cpp | 85 +++++++++++++++ exe.cpp | 2 +- fixed.hpp | 2 +- fletcher.hpp | 3 +- float.hpp | 2 +- io.cpp | 1 + iterator.hpp | 2 +- json/schema.cpp | 1 + maths.cpp | 7 +- noise/basis.cpp | 3 +- noise/fractal.cpp | 20 ++++ region.cpp | 1 - time.cpp | 2 +- types.cpp | 170 ------------------------------ types.hpp | 153 +-------------------------- types/bits.hpp | 69 ++++++++++++ types/casts.hpp | 87 +++++++++++++++ types/string.cpp | 38 +++++++ enable_if.hpp => types/string.hpp | 18 ++-- types/traits.hpp | 43 ++++++++ 21 files changed, 371 insertions(+), 345 deletions(-) delete mode 100644 types.cpp create mode 100644 types/bits.hpp create mode 100644 types/casts.hpp create mode 100644 types/string.cpp rename enable_if.hpp => types/string.hpp (74%) create mode 100644 types/traits.hpp diff --git a/Makefile.am b/Makefile.am index 5a90ab79..5066d1d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,7 +21,6 @@ UTIL_FILES = \ crc.hpp \ debug.cpp \ debug.hpp \ - enable_if.hpp \ endian.cpp \ endian.hpp \ except.cpp \ @@ -99,8 +98,12 @@ UTIL_FILES = \ string.hpp \ time.cpp \ time.hpp \ - types.cpp \ types.hpp \ + types/bits.hpp \ + types/casts.hpp \ + types/string.cpp \ + types/string.hpp \ + types/traits.hpp \ vector.cpp \ vector.hpp \ version.cpp \ diff --git a/endian.cpp b/endian.cpp index b69d7c53..e7477aa8 100644 --- a/endian.cpp +++ b/endian.cpp @@ -18,3 +18,88 @@ */ #include "endian.hpp" + +#include +#include + +using std::is_fundamental; +using std::is_unsigned; + +#ifdef WORDS_BIGENDIAN +/* Big endian doesn't need swapping */ +template +T hton (T val) { + static_assert (is_fundamental (), "hton implementation assumes fundamental types"); + static_assert (is_unsigned (), "hton implementation does not handle signed"); + return val; +} + +template +T ntoh (T val) { + static_assert (is_fundamental (), "ntoh implementation assumes fundamental types"); + static_assert (is_unsigned (), "ntoh implementation does not handle signed"); + return val; +} + +template <> uint8_t hton ( uint8_t); +template <> uint16_t hton (uint16_t); +template <> uint32_t hton (uint32_t); +template <> uint64_t hton (uint64_t); + +template <> uint8_t ntoh ( uint8_t); +template <> uint16_t ntoh (uint16_t); +template <> uint32_t ntoh (uint32_t); +template <> uint64_t ntoh (uint64_t); + +#else + +static void +byte_swap (uint8_t *restrict dst, uint8_t *restrict src, size_t len) { + for (unsigned int i = 0; i < len; ++i) + dst[len - i - 1] = src[i]; +} + + +template +T +hton (T i) { + // Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes. + static_assert (is_fundamental ::value, "hton implementation assumes fundamental types"); + static_assert (is_unsigned ::value, "hton implementation does not handle signed"); + + T swapped; + byte_swap (reinterpret_cast (&swapped), + reinterpret_cast (&i), + sizeof (T)); + return swapped; +} + + +template +T +ntoh (T i) { + // Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes. + static_assert (is_fundamental ::value, "ntoh implementation assumes fundamental types"); + static_assert (is_unsigned ::value, "ntoh implementation does not handle signed"); + + T swapped; + byte_swap (reinterpret_cast (&swapped), + reinterpret_cast (&i), + sizeof (T)); + return swapped; +} + +template <> uint8_t hton (uint8_t i) { return i; } +template <> uint8_t ntoh (uint8_t i) { return i; } + +template uint16_t ntoh (uint16_t); +template uint32_t ntoh (uint32_t); +template uint64_t ntoh (uint64_t); + +template uint16_t hton (uint16_t); +template uint32_t hton (uint32_t); +template uint64_t hton (uint64_t); + +#endif + + diff --git a/exe.cpp b/exe.cpp index 3514d53b..0ad17fef 100644 --- a/exe.cpp +++ b/exe.cpp @@ -24,8 +24,8 @@ #if defined(PLATFORM_LINUX) -#include "types.hpp" #include "except.hpp" +#include "types/casts.hpp" #include #include diff --git a/fixed.hpp b/fixed.hpp index 516acb2c..9be70bd9 100644 --- a/fixed.hpp +++ b/fixed.hpp @@ -20,7 +20,7 @@ #ifndef __UTIL_FIXED_HPP #define __UTIL_FIXED_HPP -#include "types.hpp" +#include "types/bits.hpp" #include diff --git a/fletcher.hpp b/fletcher.hpp index ca42887a..e638881f 100644 --- a/fletcher.hpp +++ b/fletcher.hpp @@ -20,11 +20,12 @@ #ifndef __UTIL_FLETCHER_HPP #define __UTIL_FLETCHER_HPP -#include "types.hpp" +#include "types/bits.hpp" #include #include + template typename bits_type::uint fletcher (const void *restrict _data, size_t size) { diff --git a/float.hpp b/float.hpp index 935c58ec..e6167cd0 100644 --- a/float.hpp +++ b/float.hpp @@ -1,7 +1,7 @@ #ifndef __FLOAT_HPP #define __FLOAT_HPP -#include "types.hpp" +#include "types/bits.hpp" #include "debug.hpp" diff --git a/io.cpp b/io.cpp index ba12f133..383d12c5 100644 --- a/io.cpp +++ b/io.cpp @@ -22,6 +22,7 @@ #include "debug.hpp" #include "except.hpp" #include "platform.hpp" +#include "types/casts.hpp" #include #include diff --git a/iterator.hpp b/iterator.hpp index 63f11eb7..348d878a 100644 --- a/iterator.hpp +++ b/iterator.hpp @@ -21,7 +21,7 @@ #ifndef __UTIL_ITERATOR_HPP #define __UTIL_ITERATOR_HPP -#include "types.hpp" +#include "types/traits.hpp" template diff --git a/json/schema.cpp b/json/schema.cpp index 08a6513e..d2408969 100644 --- a/json/schema.cpp +++ b/json/schema.cpp @@ -20,6 +20,7 @@ #include "../json.hpp" +#include "../debug.hpp" #include "../maths.hpp" #include diff --git a/maths.cpp b/maths.cpp index 8d91ea4b..4e681b4a 100644 --- a/maths.cpp +++ b/maths.cpp @@ -19,7 +19,6 @@ #include "maths.hpp" -#include "enable_if.hpp" #include "float.hpp" #include @@ -38,7 +37,7 @@ template int pow2( int); template bool is_pow2 (T value) { - typedef typename enable_if::value, bool>::type return_type; + typedef typename std::enable_if::value, bool>::type return_type; return (return_type)(value && !(value & (value - 1))); } @@ -82,7 +81,7 @@ almost_equal (const double &a, const double &b) template -typename enable_if::value, T>::type +typename std::enable_if::value, T>::type round_up (T value, T align) { CHECK_HARD (align > 1); return (value + align - 1) / align; @@ -92,7 +91,7 @@ round_up (T value, T align) { template T round_pow2 (T value) { - typedef typename enable_if::value, T>::type return_type; + typedef typename std::enable_if::value, T>::type return_type; --value; diff --git a/noise/basis.cpp b/noise/basis.cpp index de981184..e400e9f2 100644 --- a/noise/basis.cpp +++ b/noise/basis.cpp @@ -20,9 +20,10 @@ #include "noise/basis.hpp" #include "noise/lut.hpp" -#include "../vector.hpp" +#include "../debug.hpp" #include "../point.hpp" #include "../random.hpp" +#include "../vector.hpp" #include diff --git a/noise/fractal.cpp b/noise/fractal.cpp index 2d55aa46..e8304eb6 100644 --- a/noise/fractal.cpp +++ b/noise/fractal.cpp @@ -51,6 +51,16 @@ util::noise::fractal::eval (double, double) const /////////////////////////////////////////////////////////////////////////////// +template +util::noise::fbm::fbm (unsigned _octaves, + double _frequency, + double _lacunarity, + basis::seed_t _seed): + fractal (_octaves, _frequency, _lacunarity), + basis (_seed) +{ ; } + + template util::noise::fbm::fbm () { ; } @@ -85,6 +95,16 @@ template struct util::noise::fbm>; /////////////////////////////////////////////////////////////////////////////// +template +util::noise::musgrave::musgrave (unsigned _octaves, + double _frequency, + double _lacunarity, + basis::seed_t _seed): + fractal (_octaves, _frequency, _lacunarity), + basis (_seed) +{ ; } + + template util::noise::musgrave::musgrave () { ; } diff --git a/region.cpp b/region.cpp index 80555ef8..a1f4048a 100644 --- a/region.cpp +++ b/region.cpp @@ -20,7 +20,6 @@ #include "region.hpp" -#include "enable_if.hpp" #include "debug.hpp" #include diff --git a/time.cpp b/time.cpp index 190cd68e..be91a0df 100644 --- a/time.cpp +++ b/time.cpp @@ -21,7 +21,7 @@ #include "debug.hpp" #include "platform.hpp" -#include "types.hpp" +#include "types/casts.hpp" using namespace util; diff --git a/types.cpp b/types.cpp deleted file mode 100644 index e32148ef..00000000 --- a/types.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of libgim. - * - * libgim is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * libgim is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with libgim. If not, see . - * - * Copyright 2011 Danny Robson - */ - -#include "types.hpp" - -#include - -using namespace std; - - -#define do_type_to_string(T) \ -template <> std::string type_to_string (void) { return #T; } \ -template <> std::string type_to_string (void) { return "const " #T; } - -do_type_to_string (float) -do_type_to_string (double) - -do_type_to_string ( int8_t) -do_type_to_string ( int16_t) -do_type_to_string ( int32_t) -do_type_to_string ( int64_t) - -do_type_to_string ( uint8_t) -do_type_to_string (uint16_t) -do_type_to_string (uint32_t) -do_type_to_string (uint64_t) - -#ifdef WORDS_BIGENDIAN -/* Big endian doesn't need swapping */ -template -T hton (T val) { - static_assert (is_fundamental (), "hton implementation assumes fundamental types"); - static_assert (is_unsigned (), "hton implementation does not handle signed"); - return val; -} - -template -T ntoh (T val) { - static_assert (is_fundamental (), "ntoh implementation assumes fundamental types"); - static_assert (is_unsigned (), "ntoh implementation does not handle signed"); - return val; -} - -template <> uint8_t hton ( uint8_t); -template <> uint16_t hton (uint16_t); -template <> uint32_t hton (uint32_t); -template <> uint64_t hton (uint64_t); - -template <> uint8_t ntoh ( uint8_t); -template <> uint16_t ntoh (uint16_t); -template <> uint32_t ntoh (uint32_t); -template <> uint64_t ntoh (uint64_t); - -#else - -static void -byte_swap (uint8_t *restrict dst, uint8_t *restrict src, size_t len) { - for (unsigned int i = 0; i < len; ++i) - dst[len - i - 1] = src[i]; -} - - -template -T -hton (T i) { - // Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes. - static_assert (is_fundamental ::value, "hton implementation assumes fundamental types"); - static_assert (is_unsigned ::value, "hton implementation does not handle signed"); - - T swapped; - byte_swap (reinterpret_cast (&swapped), - reinterpret_cast (&i), - sizeof (T)); - return swapped; -} - - -template -T -ntoh (T i) { - // Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes. - static_assert (is_fundamental ::value, "ntoh implementation assumes fundamental types"); - static_assert (is_unsigned ::value, "ntoh implementation does not handle signed"); - - T swapped; - byte_swap (reinterpret_cast (&swapped), - reinterpret_cast (&i), - sizeof (T)); - return swapped; -} - -template <> uint8_t hton (uint8_t i) { return i; } -template <> uint8_t ntoh (uint8_t i) { return i; } - -template uint16_t ntoh (uint16_t); -template uint32_t ntoh (uint32_t); -template uint64_t ntoh (uint64_t); - -template uint16_t hton (uint16_t); -template uint32_t hton (uint32_t); -template uint64_t hton (uint64_t); - -#endif - - -fourcc -fourcc::from_chars (uint8_t a, uint8_t b, uint8_t c, uint8_t d) { - fourcc lhs; - - lhs.data[0] = a; - lhs.data[1] = b; - lhs.data[2] = c; - lhs.data[3] = d; - - return lhs; -} - - -fourcc -fourcc::from_str (const char data[4]) { - fourcc lhs; - - lhs.data[0] = (uint8_t)data[0]; - lhs.data[1] = (uint8_t)data[1]; - lhs.data[2] = (uint8_t)data[2]; - lhs.data[3] = (uint8_t)data[3]; - - return lhs; -} - - -bool -fourcc::operator== (const char rhs[4]) const { - return data[0] == rhs[0] && - data[1] == rhs[1] && - data[2] == rhs[2] && - data[3] == rhs[3]; -} - - -fourcc::operator uint32_t (void) const { - return (uint32_t)(data[0] << 24U | - data[1] << 16U | - data[2] << 8U | - data[3]); -} - - -ostream& -operator<< (ostream &os, fourcc f) { - os << f.data[0] << f.data[1] << f.data[2] << f.data[3]; - return os; -} - diff --git a/types.hpp b/types.hpp index 4089a32d..e9a42b29 100644 --- a/types.hpp +++ b/types.hpp @@ -20,124 +20,10 @@ #ifndef __TYPES_HPP #define __TYPES_HPP -#include "annotations.hpp" -#include "debug.hpp" -#include "enable_if.hpp" - #include -#include -#include +#include #include -template -struct bits_type; - - -template <> struct bits_type< 8> { - static const bool has_floating = false; - - typedef uint8_t uint; - typedef int8_t sint; - typedef uint8_t floating; -}; - - -template <> struct bits_type<16> { - static const bool has_floating = false; - - typedef uint16_t uint; - typedef int16_t sint; - typedef uint16_t floating; -}; - - -template <> struct bits_type<32> { - static const bool has_floating = true; - - typedef uint32_t uint; - typedef int32_t sint; - typedef float floating; -}; - - -template <> struct bits_type<64> { - static const bool has_floating = true; - - typedef uint64_t uint; - typedef int64_t sint; - typedef double floating; -}; - - -template -struct sized_type : public bits_type -{ }; - - -template -std::string -type_to_string (void); - - -namespace detail { - template - T - _sign_cast (const typename enable_if::value && - std::is_signed::value, V>::type v) - { - CHECK_HARD (v >= 0); - return static_cast (v); - } - - - template - T - _sign_cast (const typename enable_if::value && - std::is_unsigned::value, V>::type v) - { - CHECK_HARD (v < std::numeric_limits::max () / 2); - return static_cast (v); - } -} - -/// Safely cast a numeric type to its (un)signed counterpart, aborting if the -/// dynamically checked result is not representable. May be optimised out if -/// NDEBUG is defined. -template -T -sign_cast (const V v) - { return detail::_sign_cast(v); } - - -namespace detail { - // Same sign, no possibility of truncation with larger target type - template - T - _trunc_cast (const typename enable_if= sizeof (V) && - std::is_signed::value == std::is_signed::value, V>::type v) - { return v; } - - - template - T - _trunc_cast (const typename enable_if::value == std::is_signed::value, V>::type v) { - CHECK_HARD (v <= std::numeric_limits::max ()); - checK_hard (v >= std::numeric_limits::min ()); - - return static_cast (v); - } -} - - -template -T -trunc_cast (V v) - { return detail::_trunc_cast (v); } - - /// Returns the number of elements of a statically allocated array template size_t elems(T (&)[N]) @@ -145,43 +31,10 @@ size_t elems(T (&)[N]) template -std::unique_ptr make_unique(Args&&... args) { +std::unique_ptr +make_unique(Args&&... args) { return std::unique_ptr (new T(std::forward(args)...)); } -struct fourcc { - uint8_t data[4]; - - static fourcc from_str(const char[4]); - static fourcc from_chars(uint8_t, uint8_t, uint8_t, uint8_t); - - bool operator== (const char[4]) const; - operator uint32_t (void) const; -}; - -std::ostream& operator<< (std::ostream&, fourcc); - - -template struct is_dereferencable : std::false_type { }; -template struct is_dereferencable : std::true_type { }; -template struct is_dereferencable> : std::true_type { }; -template struct is_dereferencable> : std::true_type { }; -template struct is_dereferencable> : std::true_type { }; -template struct is_dereferencable> : std::true_type { }; - - -template struct dereferenced_type { - typedef typename std::enable_if< - std::is_pointer::value, - std::remove_pointer - >::type type; -}; - -template struct dereferenced_type> { typedef T type; }; -template struct dereferenced_type> { typedef T type; }; -template struct dereferenced_type> { typedef T type; }; -template struct dereferenced_type> { typedef T type; }; - - #endif // __TYPES_HPP diff --git a/types/bits.hpp b/types/bits.hpp new file mode 100644 index 00000000..e1e90141 --- /dev/null +++ b/types/bits.hpp @@ -0,0 +1,69 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + +#ifndef __UTIL_TYPES_BITS_HPP +#define __UTIL_TYPES_BITS_HPP + +#include + +template +struct bits_type; + + +template <> struct bits_type< 8> { + static const bool has_floating = false; + + typedef uint8_t uint; + typedef int8_t sint; + typedef uint8_t floating; +}; + + +template <> struct bits_type<16> { + static const bool has_floating = false; + + typedef uint16_t uint; + typedef int16_t sint; + typedef uint16_t floating; +}; + + +template <> struct bits_type<32> { + static const bool has_floating = true; + + typedef uint32_t uint; + typedef int32_t sint; + typedef float floating; +}; + + +template <> struct bits_type<64> { + static const bool has_floating = true; + + typedef uint64_t uint; + typedef int64_t sint; + typedef double floating; +}; + + +template +struct sized_type : public bits_type +{ }; + +#endif diff --git a/types/casts.hpp b/types/casts.hpp new file mode 100644 index 00000000..7c443ea4 --- /dev/null +++ b/types/casts.hpp @@ -0,0 +1,87 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + +#ifndef __UTIL_TYPES_CASTS_HPP +#define __UTIL_TYPES_CASTS_HPP + +#include "../debug.hpp" + +#include +#include + + +namespace detail { + template + T + _sign_cast (const typename std::enable_if::value && + std::is_signed::value, V>::type v) + { + CHECK_HARD (v >= 0); + return static_cast (v); + } + + + template + T + _sign_cast (const typename std::enable_if::value && + std::is_unsigned::value, V>::type v) + { + CHECK_HARD (v < std::numeric_limits::max () / 2); + return static_cast (v); + } +} + +/// Safely cast a numeric type to its (un)signed counterpart, aborting if the +/// dynamically checked result is not representable. May be optimised out if +/// NDEBUG is defined. +template +T +sign_cast (const V v) + { return detail::_sign_cast(v); } + + +namespace detail { + // Same sign, no possibility of truncation with larger target type + template + T + _trunc_cast (const typename std::enable_if= sizeof (V) && + std::is_signed::value == std::is_signed::value, V>::type v) + { return v; } + + + template + T + _trunc_cast (const typename std::enable_if::value == std::is_signed::value, V>::type v) { + CHECK_HARD (v <= std::numeric_limits::max ()); + checK_hard (v >= std::numeric_limits::min ()); + + return static_cast (v); + } +} + + +template +T +trunc_cast (V v) + { return detail::_trunc_cast (v); } + +#endif diff --git a/types/string.cpp b/types/string.cpp new file mode 100644 index 00000000..15ca347c --- /dev/null +++ b/types/string.cpp @@ -0,0 +1,38 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + +#include "string.hpp" + +#define do_type_to_string(T) \ +template <> std::string type_to_string (void) { return #T; } \ +template <> std::string type_to_string (void) { return "const " #T; } + +do_type_to_string (float) +do_type_to_string (double) + +do_type_to_string ( int8_t) +do_type_to_string ( int16_t) +do_type_to_string ( int32_t) +do_type_to_string ( int64_t) + +do_type_to_string ( uint8_t) +do_type_to_string (uint16_t) +do_type_to_string (uint32_t) +do_type_to_string (uint64_t) + diff --git a/enable_if.hpp b/types/string.hpp similarity index 74% rename from enable_if.hpp rename to types/string.hpp index 18d197a4..0b7d6c41 100644 --- a/enable_if.hpp +++ b/types/string.hpp @@ -14,20 +14,16 @@ * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * - * Copyright 2010 Danny Robson + * Copyright 2011 Danny Robson */ -#ifndef __ENABLE_IF_HPP -#define __ENABLE_IF_HPP - -template -struct enable_if { - typedef T type; -}; +#ifndef __UTIL_TYPES_STRING_HPP +#define __UTIL_TYPES_STRING_HPP +#include template -struct enable_if { }; +std::string +type_to_string (void); - -#endif // __ENABLE_IF_HPP +#endif diff --git a/types/traits.hpp b/types/traits.hpp new file mode 100644 index 00000000..e10b93c4 --- /dev/null +++ b/types/traits.hpp @@ -0,0 +1,43 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2012 Danny Robson + */ + +#ifndef __UTIL_TYPES_TRAITS_HPP +#define __UTIL_TYPES_TRAITS_HPP + +template struct is_dereferencable : std::false_type { }; +template struct is_dereferencable : std::true_type { }; +template struct is_dereferencable> : std::true_type { }; +template struct is_dereferencable> : std::true_type { }; +template struct is_dereferencable> : std::true_type { }; +template struct is_dereferencable> : std::true_type { }; + + +template struct dereferenced_type { + typedef typename std::enable_if< + std::is_pointer::value, + std::remove_pointer + >::type type; +}; + +template struct dereferenced_type> { typedef T type; }; +template struct dereferenced_type> { typedef T type; }; +template struct dereferenced_type> { typedef T type; }; +template struct dereferenced_type> { typedef T type; }; + +#endif