Logo ROOT   6.21/01
Reference Guide
TypeTraits.hxx
Go to the documentation of this file.
1 // @(#)root/foundation:
2 // Author: Axel Naumann, Enrico Guiraud, June 2017
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TypeTraits
13 #define ROOT_TypeTraits
14 
15 #include <memory> // shared_ptr, unique_ptr for IsSmartOrDumbPtr
16 #include <type_traits>
17 #include <vector> // for IsContainer
18 #include "ROOT/RSpan.hxx" // for IsContainer
19 
20 namespace ROOT {
21 
22 /// ROOT type_traits extensions
23 namespace TypeTraits {
24 /// Lightweight storage for a collection of types.
25 /// Differently from std::tuple, no instantiation of objects of stored types is performed
26 template <typename... Types>
27 struct TypeList {
28  static constexpr std::size_t list_size = sizeof...(Types);
29 };
30 } // end ns TypeTraits
31 
32 namespace Detail {
33 template <typename T> constexpr auto HasCallOp(int /*goodOverload*/) -> decltype(&T::operator(), true) { return true; }
34 template <typename T> constexpr bool HasCallOp(char /*badOverload*/) { return false; }
35 
36 /// Extract types from the signature of a callable object. See CallableTraits.
37 template <typename T, bool HasCallOp = ROOT::Detail::HasCallOp<T>(0)>
39 
40 // Extract signature of operator() and delegate to the appropriate CallableTraitsImpl overloads
41 template <typename T>
42 struct CallableTraitsImpl<T, true> {
46 };
47 
48 // lambdas, std::function, const member functions
49 template <typename R, typename T, typename... Args>
50 struct CallableTraitsImpl<R (T::*)(Args...) const, false> {
53  using ret_type = R;
54 };
55 
56 // mutable lambdas and functor classes, non-const member functions
57 template <typename R, typename T, typename... Args>
58 struct CallableTraitsImpl<R (T::*)(Args...), false> {
61  using ret_type = R;
62 };
63 
64 // function pointers
65 template <typename R, typename... Args>
66 struct CallableTraitsImpl<R (*)(Args...), false> {
69  using ret_type = R;
70 };
71 
72 // free functions
73 template <typename R, typename... Args>
74 struct CallableTraitsImpl<R(Args...), false> {
77  using ret_type = R;
78 };
79 } // end ns Detail
80 
81 namespace TypeTraits {
82 
83 ///\class ROOT::TypeTraits::
84 template <class T>
85 class IsSmartOrDumbPtr : public std::integral_constant<bool, std::is_pointer<T>::value> {
86 };
87 
88 template <class P>
89 class IsSmartOrDumbPtr<std::shared_ptr<P>> : public std::true_type {
90 };
91 
92 template <class P>
93 class IsSmartOrDumbPtr<std::unique_ptr<P>> : public std::true_type {
94 };
95 
96 /// Check for container traits.
97 template <typename T>
98 struct IsContainer {
99  using Test_t = typename std::decay<T>::type;
100 
101  template <typename A>
102  static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
103  decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
104  decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
105  typename A::const_iterator *pci = nullptr)
106  {
107  using It_t = typename A::iterator;
108  using CIt_t = typename A::const_iterator;
109  using V_t = typename A::value_type;
110  return std::is_same<Test_t, std::vector<bool>>::value ||
111  (std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
112  std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
113  std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value);
114  }
115 
116  template <typename A>
117  static constexpr bool Test(...)
118  {
119  return false;
120  }
121 
122  static constexpr bool value = Test<Test_t>(nullptr);
123 };
124 
125 template<typename T>
126 struct IsContainer<std::span<T>> {
127  static constexpr bool value = true;
128 };
129 
130 /// Checks for signed integers types that are not characters
131 template<class T>
132 struct IsSignedNumeral : std::integral_constant<bool,
133  std::is_integral<T>::value &&
134  std::is_signed<T>::value &&
135  !std::is_same<T, char>::value
136 > {};
137 
138 /// Checks for unsigned integer types that are not characters
139 template<class T>
140 struct IsUnsignedNumeral : std::integral_constant<bool,
141  std::is_integral<T>::value &&
142  !std::is_signed<T>::value &&
143  !std::is_same<T, char>::value
144 > {};
145 
146 /// Checks for floating point types (that are not characters)
147 template<class T>
148 using IsFloatNumeral = std::is_floating_point<T>;
149 
150 /// Extract types from the signature of a callable object.
151 /// The `CallableTraits` struct contains three type aliases:
152 /// - arg_types: a `TypeList` of all types in the signature, decayed through std::decay
153 /// - arg_types_nodecay: a `TypeList` of all types in the signature, including cv-qualifiers
154 template<typename F>
156 
157 // Return first of a variadic list of types.
158 template <typename T, typename... Rest>
160  using type = T;
161 };
162 
163 template <typename... Types>
164 using TakeFirstType_t = typename TakeFirstType<Types...>::type;
165 
166 // Remove first type from a variadic list of types, return a TypeList containing the rest.
167 // e.g. RemoveFirst_t<A,B,C> is TypeList<B,C>
168 template <typename T, typename... Rest>
169 struct RemoveFirst {
170  using type = TypeList<Rest...>;
171 };
172 
173 template <typename... Args>
174 using RemoveFirst_t = typename RemoveFirst<Args...>::type;
175 
176 /// Return first of possibly many template parameters.
177 /// For non-template types, the result is void
178 /// e.g. TakeFirstParameter<U<A,B>> is A
179 /// TakeFirstParameter<T> is void
180 template <typename T>
182  using type = void;
183 };
184 
185 template <template <typename...> class Template, typename T, typename... Rest>
186 struct TakeFirstParameter<Template<T, Rest...>> {
187  using type = T;
188 };
189 
190 template <typename T>
192 
193 /// Remove first of possibly many template parameters.
194 /// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
195 template <typename>
197 };
198 
199 template <typename T, template <typename...> class U, typename... Rest>
200 struct RemoveFirstParameter<U<T, Rest...>> {
201  using type = U<Rest...>;
202 };
203 
204 template <typename T>
206 
207 template <typename T>
209 
210  template <typename V>
211  using Begin_t = typename V::const_iterator (V::*)() const;
212 
213  template <typename V>
214  using End_t = typename V::const_iterator (V::*)() const;
215 
216  template <typename V>
217  static constexpr auto Check(int)
218  -> decltype(static_cast<Begin_t<V>>(&V::begin), static_cast<End_t<V>>(&V::end), true)
219  {
220  return true;
221  }
222 
223  template <typename V>
224  static constexpr bool Check(...)
225  {
226  return false;
227  }
228 
229  static constexpr bool const value = Check<T>(0);
230 };
231 
232 } // ns TypeTraits
233 } // ns ROOT
234 #endif // ROOT_TTypeTraits
Remove first of possibly many template parameters.
Definition: TypeTraits.hxx:196
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
Definition: TypeTraits.hxx:205
ROOT::TypeTraits::TypeList< typename std::decay< Args >::type... > arg_types
Definition: TypeTraits.hxx:59
static constexpr bool Check(...)
Definition: TypeTraits.hxx:224
Returns the available number of logical cores.
Definition: StringConv.hxx:21
typename TakeFirstParameter< T >::type TakeFirstParameter_t
Definition: TypeTraits.hxx:191
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::TypeTraits::TypeList< Args... > arg_types_nodecay
Definition: TypeTraits.hxx:76
typename V::const_iterator(V::*)() const End_t
Definition: TypeTraits.hxx:214
static constexpr bool const value
Definition: TypeTraits.hxx:229
STL namespace.
static double A[]
typename CallableTraitsImpl< decltype(&T::operator())>::arg_types_nodecay arg_types_nodecay
Definition: TypeTraits.hxx:44
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
typename RemoveFirst< Args... >::type RemoveFirst_t
Definition: TypeTraits.hxx:174
static constexpr std::size_t list_size
Definition: TypeTraits.hxx:28
static constexpr auto Check(int) -> decltype(static_cast< Begin_t< V >>(&V::begin), static_cast< End_t< V >>(&V::end), true)
Definition: TypeTraits.hxx:217
typename CallableTraitsImpl< decltype(&T::operator())>::arg_types arg_types
Definition: TypeTraits.hxx:43
static constexpr bool value
Definition: TypeTraits.hxx:122
static constexpr bool Test(...)
Definition: TypeTraits.hxx:117
std::is_floating_point< T > IsFloatNumeral
Checks for floating point types (that are not characters)
Definition: TypeTraits.hxx:148
ROOT::TypeTraits::TypeList< typename std::decay< Args >::type... > arg_types
Definition: TypeTraits.hxx:75
typename V::const_iterator(V::*)() const Begin_t
Definition: TypeTraits.hxx:211
ROOT::TypeTraits::TypeList< Args... > arg_types_nodecay
Definition: TypeTraits.hxx:68
constexpr auto HasCallOp(int) -> decltype(&T::operator(), true)
Definition: TypeTraits.hxx:33
static constexpr bool Test(A *pt, A const *cpt=nullptr, decltype(pt->begin()) *=nullptr, decltype(pt->end()) *=nullptr, decltype(cpt->begin()) *=nullptr, decltype(cpt->end()) *=nullptr, typename A::iterator *pi=nullptr, typename A::const_iterator *pci=nullptr)
Definition: TypeTraits.hxx:102
TPaveText * pt
ROOT::TypeTraits::TypeList< typename std::decay< Args >::type... > arg_types
Definition: TypeTraits.hxx:67
typename TakeFirstType< Types... >::type TakeFirstType_t
Definition: TypeTraits.hxx:164
Lightweight storage for a collection of types.
Definition: TypeTraits.hxx:27
ROOT::TypeTraits::TypeList< typename std::decay< Args >::type... > arg_types
Definition: TypeTraits.hxx:51
int type
Definition: TGX11.cxx:120
Extract types from the signature of a callable object. See CallableTraits.
Definition: TypeTraits.hxx:38
typedef void((*Func_t)())
static constexpr double pi
typename std::decay< T >::type Test_t
Definition: TypeTraits.hxx:99
ROOT::TypeTraits::TypeList< Args... > arg_types_nodecay
Definition: TypeTraits.hxx:60
Check for container traits.
Definition: TypeTraits.hxx:98
Checks for signed integers types that are not characters.
Definition: TypeTraits.hxx:132
typename CallableTraitsImpl< decltype(&T::operator())>::ret_type ret_type
Definition: TypeTraits.hxx:45
Checks for unsigned integer types that are not characters.
Definition: TypeTraits.hxx:140
Return first of possibly many template parameters.
Definition: TypeTraits.hxx:181