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
15namespace dmlc {
16/*!
17 * \brief whether a type is pod type
18 * \tparam T the type to query
19 */
20template<typename T>
21struct 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 */
36template<typename T>
37struct 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 */
51template<typename T>
52struct 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 */
66template<typename T>
67struct 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 */
85template<typename T>
86struct 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 */
100template<typename T>
101inline 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 */
109template<typename T>
110struct 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*/
122template<bool cond, typename Then, typename Else>
123struct 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
144DMLC_DECLARE_TRAITS(is_pod, char, true);
145DMLC_DECLARE_TRAITS(is_pod, int8_t, true);
146DMLC_DECLARE_TRAITS(is_pod, int16_t, true);
147DMLC_DECLARE_TRAITS(is_pod, int32_t, true);
148DMLC_DECLARE_TRAITS(is_pod, int64_t, true);
149DMLC_DECLARE_TRAITS(is_pod, uint8_t, true);
150DMLC_DECLARE_TRAITS(is_pod, uint16_t, true);
151DMLC_DECLARE_TRAITS(is_pod, uint32_t, true);
152DMLC_DECLARE_TRAITS(is_pod, uint64_t, true);
153DMLC_DECLARE_TRAITS(is_pod, float, true);
154DMLC_DECLARE_TRAITS(is_pod, double, true);
155
156DMLC_DECLARE_TRAITS(is_integral, char, true);
157DMLC_DECLARE_TRAITS(is_integral, int8_t, true);
158DMLC_DECLARE_TRAITS(is_integral, int16_t, true);
159DMLC_DECLARE_TRAITS(is_integral, int32_t, true);
160DMLC_DECLARE_TRAITS(is_integral, int64_t, true);
161DMLC_DECLARE_TRAITS(is_integral, uint8_t, true);
162DMLC_DECLARE_TRAITS(is_integral, uint16_t, true);
163DMLC_DECLARE_TRAITS(is_integral, uint32_t, true);
164DMLC_DECLARE_TRAITS(is_integral, uint64_t, true);
165
166DMLC_DECLARE_TRAITS(is_floating_point, float, true);
167DMLC_DECLARE_TRAITS(is_floating_point, double, true);
168
169#endif
170
171DMLC_DECLARE_TYPE_NAME(float, "float");
172DMLC_DECLARE_TYPE_NAME(double, "double");
173DMLC_DECLARE_TYPE_NAME(int, "int");
174DMLC_DECLARE_TYPE_NAME(int64_t, "long");
175DMLC_DECLARE_TYPE_NAME(uint32_t, "int (non-negative)");
176DMLC_DECLARE_TYPE_NAME(uint64_t, "long (non-negative)");
177DMLC_DECLARE_TYPE_NAME(std::string, "string");
178DMLC_DECLARE_TYPE_NAME(bool, "boolean");
179DMLC_DECLARE_TYPE_NAME(void*, "ptr");
180
181template<typename Then, typename Else>
182struct IfThenElseType<true, Then, Else> {
183 typedef Then Type;
184};
185
186template<typename Then, typename Else>
187struct IfThenElseType<false, Then, Else> {
188 typedef Else Type;
189};
190//! \endcond
191} // namespace dmlc
192#endif // DMLC_TYPE_TRAITS_H_
193