File: spp_traits.h

package info (click to toggle)
rapmap 0.15.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,228 kB
  • sloc: cpp: 48,810; ansic: 4,686; sh: 215; python: 82; makefile: 15
file content (125 lines) | stat: -rw-r--r-- 5,584 bytes parent folder | download | duplicates (17)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#if !defined(spp_traits_h_guard)
#define spp_traits_h_guard

#include "spp_config.h"

template<int S, int H> class HashObject; // for Google's benchmark, not in spp namespace!

namespace spp_
{

// ---------------------------------------------------------------------------
//                       type_traits we need
// ---------------------------------------------------------------------------
template<class T, T v>
struct integral_constant { static const T value = v; };

template <class T, T v> const T integral_constant<T, v>::value;

typedef integral_constant<bool, true>  true_type;
typedef integral_constant<bool, false> false_type;

typedef integral_constant<int, 0>      zero_type;
typedef integral_constant<int, 1>      one_type;
typedef integral_constant<int, 2>      two_type;
typedef integral_constant<int, 3>      three_type;

template<typename T, typename U> struct is_same : public false_type { };
template<typename T> struct is_same<T, T> : public true_type { };

template<typename T> struct remove_const { typedef T type; };
template<typename T> struct remove_const<T const> { typedef T type; };

template<typename T> struct remove_volatile { typedef T type; };
template<typename T> struct remove_volatile<T volatile> { typedef T type; };

template<typename T> struct remove_cv 
{
    typedef typename remove_const<typename remove_volatile<T>::type>::type type;
};

// ---------------- is_integral ----------------------------------------
template <class T> struct is_integral;
template <class T> struct is_integral         : false_type { };
template<> struct is_integral<bool>           : true_type { };
template<> struct is_integral<char>           : true_type { };
template<> struct is_integral<unsigned char>  : true_type { };
template<> struct is_integral<signed char>    : true_type { };
template<> struct is_integral<short>          : true_type { };
template<> struct is_integral<unsigned short> : true_type { };
template<> struct is_integral<int>            : true_type { };
template<> struct is_integral<unsigned int>   : true_type { };
template<> struct is_integral<long>           : true_type { };
template<> struct is_integral<unsigned long>  : true_type { };
#ifdef SPP_HAS_LONG_LONG
    template<> struct is_integral<long long>  : true_type { };
    template<> struct is_integral<unsigned long long> : true_type { };
#endif
template <class T> struct is_integral<const T>          : is_integral<T> { };
template <class T> struct is_integral<volatile T>       : is_integral<T> { };
template <class T> struct is_integral<const volatile T> : is_integral<T> { };

// ---------------- is_floating_point ----------------------------------------
template <class T> struct is_floating_point;
template <class T> struct is_floating_point      : false_type { };
template<> struct is_floating_point<float>       : true_type { };
template<> struct is_floating_point<double>      : true_type { };
template<> struct is_floating_point<long double> : true_type { };
template <class T> struct is_floating_point<const T> :        is_floating_point<T> { };
template <class T> struct is_floating_point<volatile T>       : is_floating_point<T> { };
template <class T> struct is_floating_point<const volatile T> : is_floating_point<T> { };

//  ---------------- is_pointer ----------------------------------------
template <class T> struct is_pointer;
template <class T> struct is_pointer     : false_type { };
template <class T> struct is_pointer<T*> : true_type { };
template <class T> struct is_pointer<const T>          : is_pointer<T> { };
template <class T> struct is_pointer<volatile T>       : is_pointer<T> { };
template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };

//  ---------------- is_reference ----------------------------------------
template <class T> struct is_reference;
template<typename T> struct is_reference     : false_type {};
template<typename T> struct is_reference<T&> : true_type {};

//  ---------------- is_relocatable ----------------------------------------
// relocatable values can be moved around in memory using memcpy and remain
// correct. Most types are relocatable, an example of a type who is not would
// be a struct which contains a pointer to a buffer inside itself - this is the
// case for std::string in gcc 5.
// ------------------------------------------------------------------------
template <class T> struct is_relocatable;
template <class T> struct is_relocatable :
     integral_constant<bool, (is_integral<T>::value ||
                              is_floating_point<T>::value ||
                              is_pointer<T>::value
                             )>
{ };

template<int S, int H> struct is_relocatable<HashObject<S, H> > : true_type { };

template <class T> struct is_relocatable<const T>          : is_relocatable<T> { };
template <class T> struct is_relocatable<volatile T>       : is_relocatable<T> { };
template <class T> struct is_relocatable<const volatile T> : is_relocatable<T> { };
template <class A, int N> struct is_relocatable<A[N]>      : is_relocatable<A> { };
template <class T, class U> struct is_relocatable<std::pair<T, U> > :
     integral_constant<bool, (is_relocatable<T>::value && is_relocatable<U>::value)>
{ };

// A template helper used to select A or B based on a condition.
// ------------------------------------------------------------
template<bool cond, typename A, typename B>
struct if_
{
    typedef A type;
};

template<typename A, typename B>
struct if_<false, A, B> 
{
    typedef B type;
};

}  // spp_ namespace

#endif // spp_traits_h_guard