1 | /*! |
2 | * Copyright (c) 2015 by Contributors |
3 | * \file type_traits.h |
4 | * \brief type traits information header |
5 | */ |
6 | #ifndef DMLC_TYPE_TRAITS_H_ |
7 | #define DMLC_TYPE_TRAITS_H_ |
8 | |
9 | #include "./base.h" |
10 | #if DMLC_USE_CXX11 |
11 | #include <type_traits> |
12 | #endif |
13 | #include <string> |
14 | |
15 | namespace dmlc { |
16 | /*! |
17 | * \brief whether a type is pod type |
18 | * \tparam T the type to query |
19 | */ |
20 | template<typename T> |
21 | struct is_pod { |
22 | #if DMLC_USE_CXX11 |
23 | /*! \brief the value of the traits */ |
24 | static const bool value = std::is_pod<T>::value; |
25 | #else |
26 | /*! \brief the value of the traits */ |
27 | static const bool value = false; |
28 | #endif |
29 | }; |
30 | |
31 | |
32 | /*! |
33 | * \brief whether a type is integer type |
34 | * \tparam T the type to query |
35 | */ |
36 | template<typename T> |
37 | struct is_integral { |
38 | #if DMLC_USE_CXX11 |
39 | /*! \brief the value of the traits */ |
40 | static const bool value = std::is_integral<T>::value; |
41 | #else |
42 | /*! \brief the value of the traits */ |
43 | static const bool value = false; |
44 | #endif |
45 | }; |
46 | |
47 | /*! |
48 | * \brief whether a type is floating point type |
49 | * \tparam T the type to query |
50 | */ |
51 | template<typename T> |
52 | struct is_floating_point { |
53 | #if DMLC_USE_CXX11 |
54 | /*! \brief the value of the traits */ |
55 | static const bool value = std::is_floating_point<T>::value; |
56 | #else |
57 | /*! \brief the value of the traits */ |
58 | static const bool value = false; |
59 | #endif |
60 | }; |
61 | |
62 | /*! |
63 | * \brief whether a type is arithemetic type |
64 | * \tparam T the type to query |
65 | */ |
66 | template<typename T> |
67 | struct is_arithmetic { |
68 | #if DMLC_USE_CXX11 |
69 | /*! \brief the value of the traits */ |
70 | static const bool value = std::is_arithmetic<T>::value; |
71 | #else |
72 | /*! \brief the value of the traits */ |
73 | static const bool value = (dmlc::is_integral<T>::value || |
74 | dmlc::is_floating_point<T>::value); |
75 | #endif |
76 | }; |
77 | |
78 | /*! |
79 | * \brief helper class to construct a string that represents type name |
80 | * |
81 | * Specialized this class to defined type name of custom types |
82 | * |
83 | * \tparam T the type to query |
84 | */ |
85 | template<typename T> |
86 | struct type_name_helper { |
87 | /*! |
88 | * \return a string of typename. |
89 | */ |
90 | static inline std::string value() { |
91 | return "" ; |
92 | } |
93 | }; |
94 | |
95 | /*! |
96 | * \brief the string representation of type name |
97 | * \tparam T the type to query |
98 | * \return a const string of typename. |
99 | */ |
100 | template<typename T> |
101 | inline std::string type_name() { |
102 | return type_name_helper<T>::value(); |
103 | } |
104 | |
105 | /*! |
106 | * \brief whether a type have save/load function |
107 | * \tparam T the type to query |
108 | */ |
109 | template<typename T> |
110 | struct has_saveload { |
111 | /*! \brief the value of the traits */ |
112 | static const bool value = false; |
113 | }; |
114 | |
115 | /*! |
116 | * \brief template to select type based on condition |
117 | * For example, IfThenElseType<true, int, float>::Type will give int |
118 | * \tparam cond the condition |
119 | * \tparam Then the typename to be returned if cond is true |
120 | * \tparam Else typename to be returned if cond is false |
121 | */ |
122 | template<bool cond, typename Then, typename Else> |
123 | struct IfThenElseType; |
124 | |
125 | /*! \brief macro to quickly declare traits information */ |
126 | #define DMLC_DECLARE_TRAITS(Trait, Type, Value) \ |
127 | template<> \ |
128 | struct Trait<Type> { \ |
129 | static const bool value = Value; \ |
130 | } |
131 | |
132 | /*! \brief macro to quickly declare traits information */ |
133 | #define DMLC_DECLARE_TYPE_NAME(Type, Name) \ |
134 | template<> \ |
135 | struct type_name_helper<Type> { \ |
136 | static inline std::string value() { \ |
137 | return Name; \ |
138 | } \ |
139 | } |
140 | |
141 | //! \cond Doxygen_Suppress |
142 | // declare special traits when C++11 is not available |
143 | #if DMLC_USE_CXX11 == 0 |
144 | DMLC_DECLARE_TRAITS(is_pod, char, true); |
145 | DMLC_DECLARE_TRAITS(is_pod, int8_t, true); |
146 | DMLC_DECLARE_TRAITS(is_pod, int16_t, true); |
147 | DMLC_DECLARE_TRAITS(is_pod, int32_t, true); |
148 | DMLC_DECLARE_TRAITS(is_pod, int64_t, true); |
149 | DMLC_DECLARE_TRAITS(is_pod, uint8_t, true); |
150 | DMLC_DECLARE_TRAITS(is_pod, uint16_t, true); |
151 | DMLC_DECLARE_TRAITS(is_pod, uint32_t, true); |
152 | DMLC_DECLARE_TRAITS(is_pod, uint64_t, true); |
153 | DMLC_DECLARE_TRAITS(is_pod, float, true); |
154 | DMLC_DECLARE_TRAITS(is_pod, double, true); |
155 | |
156 | DMLC_DECLARE_TRAITS(is_integral, char, true); |
157 | DMLC_DECLARE_TRAITS(is_integral, int8_t, true); |
158 | DMLC_DECLARE_TRAITS(is_integral, int16_t, true); |
159 | DMLC_DECLARE_TRAITS(is_integral, int32_t, true); |
160 | DMLC_DECLARE_TRAITS(is_integral, int64_t, true); |
161 | DMLC_DECLARE_TRAITS(is_integral, uint8_t, true); |
162 | DMLC_DECLARE_TRAITS(is_integral, uint16_t, true); |
163 | DMLC_DECLARE_TRAITS(is_integral, uint32_t, true); |
164 | DMLC_DECLARE_TRAITS(is_integral, uint64_t, true); |
165 | |
166 | DMLC_DECLARE_TRAITS(is_floating_point, float, true); |
167 | DMLC_DECLARE_TRAITS(is_floating_point, double, true); |
168 | |
169 | #endif |
170 | |
171 | DMLC_DECLARE_TYPE_NAME(float, "float" ); |
172 | DMLC_DECLARE_TYPE_NAME(double, "double" ); |
173 | DMLC_DECLARE_TYPE_NAME(int, "int" ); |
174 | DMLC_DECLARE_TYPE_NAME(int64_t, "long" ); |
175 | DMLC_DECLARE_TYPE_NAME(uint32_t, "int (non-negative)" ); |
176 | DMLC_DECLARE_TYPE_NAME(uint64_t, "long (non-negative)" ); |
177 | DMLC_DECLARE_TYPE_NAME(std::string, "string" ); |
178 | DMLC_DECLARE_TYPE_NAME(bool, "boolean" ); |
179 | DMLC_DECLARE_TYPE_NAME(void*, "ptr" ); |
180 | |
181 | template<typename Then, typename Else> |
182 | struct IfThenElseType<true, Then, Else> { |
183 | typedef Then Type; |
184 | }; |
185 | |
186 | template<typename Then, typename Else> |
187 | struct IfThenElseType<false, Then, Else> { |
188 | typedef Else Type; |
189 | }; |
190 | //! \endcond |
191 | } // namespace dmlc |
192 | #endif // DMLC_TYPE_TRAITS_H_ |
193 | |