Logo ROOT   6.12/07
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/RArrayView.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::array_view<T>> {
127  static constexpr bool value = true;
128 };
129 
130 /// Extract types from the signature of a callable object.
131 /// The `CallableTraits` struct contains three type aliases:
132 /// - arg_types: a `TypeList` of all types in the signature, decayed through std::decay
133 /// - arg_types_nodecay: a `TypeList` of all types in the signature, including cv-qualifiers
134 template<typename F>
136 
137 // Return first of a variadic list of types.
138 template <typename T, typename... Rest>
140  using type = T;
141 };
142 
143 template <typename... Types>
144 using TakeFirstType_t = typename TakeFirstType<Types...>::type;
145 
146 // Remove first type from a variadic list of types, return a TypeList containing the rest.
147 // e.g. RemoveFirst_t<A,B,C> is TypeList<B,C>
148 template <typename T, typename... Rest>
149 struct RemoveFirst {
150  using type = TypeList<Rest...>;
151 };
152 
153 template <typename... Args>
154 using RemoveFirst_t = typename RemoveFirst<Args...>::type;
155 
156 /// Return first of possibly many template parameters.
157 /// For non-template types, the result is void
158 /// e.g. TakeFirstParameter<U<A,B>> is A
159 /// TakeFirstParameter<T> is void
160 template <typename T>
162  using type = void;
163 };
164 
165 template <template <typename...> class Template, typename T, typename... Rest>
166 struct TakeFirstParameter<Template<T, Rest...>> {
167  using type = T;
168 };
169 
170 template <typename T>
172 
173 /// Remove first of possibly many template parameters.
174 /// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
175 template <typename>
177 };
178 
179 template <typename T, template <typename...> class U, typename... Rest>
180 struct RemoveFirstParameter<U<T, Rest...>> {
181  using type = U<Rest...>;
182 };
183 
184 template <typename T>
186 
187 } // ns TypeTraits
188 } // ns ROOT
189 #endif // ROOT_TTypeTraits
Remove first of possibly many template parameters.
Definition: TypeTraits.hxx:176
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
Definition: TypeTraits.hxx:185
ROOT::TypeTraits::TypeList< typename std::decay< Args >::type... > arg_types
Definition: TypeTraits.hxx:59
constexpr bool HasCallOp(char)
Definition: TypeTraits.hxx:34
static constexpr double pi
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
typename TakeFirstParameter< T >::type TakeFirstParameter_t
Definition: TypeTraits.hxx:171
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::TypeTraits::TypeList< Args... > arg_types_nodecay
Definition: TypeTraits.hxx:76
STL namespace.
static double A[]
typename CallableTraitsImpl< decltype(&T::operator())>::arg_types_nodecay arg_types_nodecay
Definition: TypeTraits.hxx:44
typename RemoveFirst< Args... >::type RemoveFirst_t
Definition: TypeTraits.hxx:154
static constexpr std::size_t list_size
Definition: TypeTraits.hxx:28
typename CallableTraitsImpl< decltype(&T::operator())>::arg_types arg_types
Definition: TypeTraits.hxx:43
static constexpr bool Test(...)
Definition: TypeTraits.hxx:117
ROOT::TypeTraits::TypeList< typename std::decay< Args >::type... > arg_types
Definition: TypeTraits.hxx:75
ROOT::TypeTraits::TypeList< Args... > arg_types_nodecay
Definition: TypeTraits.hxx:68
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:144
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)())
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
constexpr Double_t R()
Definition: TMath.h:213
typename CallableTraitsImpl< decltype(&T::operator())>::ret_type ret_type
Definition: TypeTraits.hxx:45
Return first of possibly many template parameters.
Definition: TypeTraits.hxx:161