Logo ROOT   6.16/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
20namespace ROOT {
21
22/// ROOT type_traits extensions
23namespace TypeTraits {
24/// Lightweight storage for a collection of types.
25/// Differently from std::tuple, no instantiation of objects of stored types is performed
26template <typename... Types>
27struct TypeList {
28 static constexpr std::size_t list_size = sizeof...(Types);
29};
30} // end ns TypeTraits
31
32namespace Detail {
33template <typename T> constexpr auto HasCallOp(int /*goodOverload*/) -> decltype(&T::operator(), true) { return true; }
34template <typename T> constexpr bool HasCallOp(char /*badOverload*/) { return false; }
35
36/// Extract types from the signature of a callable object. See CallableTraits.
37template <typename T, bool HasCallOp = ROOT::Detail::HasCallOp<T>(0)>
39
40// Extract signature of operator() and delegate to the appropriate CallableTraitsImpl overloads
41template <typename T>
42struct CallableTraitsImpl<T, true> {
43 using arg_types = typename CallableTraitsImpl<decltype(&T::operator())>::arg_types;
44 using arg_types_nodecay = typename CallableTraitsImpl<decltype(&T::operator())>::arg_types_nodecay;
45 using ret_type = typename CallableTraitsImpl<decltype(&T::operator())>::ret_type;
46};
47
48// lambdas, std::function, const member functions
49template <typename R, typename T, typename... Args>
50struct CallableTraitsImpl<R (T::*)(Args...) const, false> {
53 using ret_type = R;
54};
55
56// mutable lambdas and functor classes, non-const member functions
57template <typename R, typename T, typename... Args>
58struct CallableTraitsImpl<R (T::*)(Args...), false> {
61 using ret_type = R;
62};
63
64// function pointers
65template <typename R, typename... Args>
66struct CallableTraitsImpl<R (*)(Args...), false> {
69 using ret_type = R;
70};
71
72// free functions
73template <typename R, typename... Args>
74struct CallableTraitsImpl<R(Args...), false> {
77 using ret_type = R;
78};
79} // end ns Detail
80
81namespace TypeTraits {
82
83///\class ROOT::TypeTraits::
84template <class T>
85class IsSmartOrDumbPtr : public std::integral_constant<bool, std::is_pointer<T>::value> {
86};
87
88template <class P>
89class IsSmartOrDumbPtr<std::shared_ptr<P>> : public std::true_type {
90};
91
92template <class P>
93class IsSmartOrDumbPtr<std::unique_ptr<P>> : public std::true_type {
94};
95
96/// Check for container traits.
97template <typename T>
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
125template<typename T>
126struct IsContainer<std::span<T>> {
127 static constexpr bool value = true;
128};
129
130/// Checks for signed integers types that are not characters
131template<class T>
132struct 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
139template<class T>
140struct 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)
147template<class T>
148using 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
154template<typename F>
156
157// Return first of a variadic list of types.
158template <typename T, typename... Rest>
160 using type = T;
161};
162
163template <typename... Types>
164using 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>
168template <typename T, typename... Rest>
170 using type = TypeList<Rest...>;
171};
172
173template <typename... Args>
174using 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
180template <typename T>
182 using type = void;
183};
184
185template <template <typename...> class Template, typename T, typename... Rest>
186struct TakeFirstParameter<Template<T, Rest...>> {
187 using type = T;
188};
189
190template <typename T>
192
193/// Remove first of possibly many template parameters.
194/// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
195template <typename>
197};
198
199template <typename T, template <typename...> class U, typename... Rest>
200struct RemoveFirstParameter<U<T, Rest...>> {
201 using type = U<Rest...>;
202};
203
204template <typename T>
206
207template <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
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
int type
Definition: TGX11.cxx:120
typedef void((*Func_t)())
typename TakeFirstParameter< T >::type TakeFirstParameter_t
Definition: TypeTraits.hxx:191
typename RemoveFirst< Args... >::type RemoveFirst_t
Definition: TypeTraits.hxx:174
std::is_floating_point< T > IsFloatNumeral
Checks for floating point types (that are not characters)
Definition: TypeTraits.hxx:148
typename TakeFirstType< Types... >::type TakeFirstType_t
Definition: TypeTraits.hxx:164
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
Definition: TypeTraits.hxx:205
TPaveText * pt
constexpr auto HasCallOp(int) -> decltype(&T::operator(), true)
Definition: TypeTraits.hxx:33
static double A[]
double T(double x)
Definition: ChebyshevPol.h:34
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
static constexpr double pi
STL namespace.
typename CallableTraitsImpl< decltype(&T::operator())>::arg_types arg_types
Definition: TypeTraits.hxx:43
typename CallableTraitsImpl< decltype(&T::operator())>::arg_types_nodecay arg_types_nodecay
Definition: TypeTraits.hxx:44
typename CallableTraitsImpl< decltype(&T::operator())>::ret_type ret_type
Definition: TypeTraits.hxx:45
Extract types from the signature of a callable object. See CallableTraits.
Definition: TypeTraits.hxx:38
typename V::const_iterator(V::*)() const Begin_t
Definition: TypeTraits.hxx:211
static constexpr bool Check(...)
Definition: TypeTraits.hxx:224
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 V::const_iterator(V::*)() const End_t
Definition: TypeTraits.hxx:214
static constexpr bool const value
Definition: TypeTraits.hxx:229
Check for container traits.
Definition: TypeTraits.hxx:98
typename std::decay< T >::type Test_t
Definition: TypeTraits.hxx:99
static constexpr bool Test(...)
Definition: TypeTraits.hxx:117
static constexpr bool value
Definition: TypeTraits.hxx:122
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
Checks for signed integers types that are not characters.
Definition: TypeTraits.hxx:136
Checks for unsigned integer types that are not characters.
Definition: TypeTraits.hxx:144
Remove first of possibly many template parameters.
Definition: TypeTraits.hxx:196
Return first of possibly many template parameters.
Definition: TypeTraits.hxx:181
Lightweight storage for a collection of types.
Definition: TypeTraits.hxx:27
static constexpr std::size_t list_size
Definition: TypeTraits.hxx:28