Templates.hpp
Go to the documentation of this file.
1 //
3 // Aurora C++ Library
4 // Copyright (c) 2012-2016 Jan Haller
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not be
20 // misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source distribution.
23 //
25 
28 
29 #ifndef AURORA_TEMPLATES_HPP
30 #define AURORA_TEMPLATES_HPP
31 
32 #include <Aurora/Config.hpp>
33 
34 #include <type_traits>
35 
36 
37 namespace aurora
38 {
39 namespace detail
40 {
41 
42  // Get type by index in list
43  template <std::size_t N, typename T0, typename T1, typename T2>
44  struct NthType;
45 
46  template <typename T0, typename T1, typename T2>
47  struct NthType<0, T0, T1, T2>
48  {
49  typedef T0 Type;
50  };
51 
52  template <typename T0, typename T1, typename T2>
53  struct NthType<1, T0, T1, T2>
54  {
55  typedef T1 Type;
56  };
57 
58  template <typename T0, typename T1, typename T2>
59  struct NthType<2, T0, T1, T2>
60  {
61  typedef T2 Type;
62  };
63 
64 
65  // Helper for FunctionSignature metafunction
66  template <typename R, std::size_t N, typename P0, typename P1, typename P2>
67  struct FunctionSignatureBase
68  {
69  typedef R ResultType;
70  static const std::size_t arity = N;
71 
72  template <std::size_t M>
73  struct Param
74  {
75  typedef typename NthType<M, P0, P1, P2>::Type Type;
76  };
77  };
78 
79 
80  // Type denoting "nothing"
81  // We don't use void because it can't be used in some contexts (parameter lists)
82  struct EmptyType {};
83 
84 
85  // Provides member typedefs for function return and parameter types:
86  // FunctionSignature<S>::ResultType return type
87  // FunctionSignature<S>::Param<N>::Type N-th parameter type (use ::template Param in dependent context)
88  template <typename S>
89  struct FunctionSignature;
90 
91  template <typename R>
92  struct FunctionSignature<R()> : FunctionSignatureBase<R, 0, EmptyType, EmptyType, EmptyType>
93  {
94  };
95 
96  template <typename R, typename P0>
97  struct FunctionSignature<R(P0)> : FunctionSignatureBase<R, 1, P0, EmptyType, EmptyType>
98  {
99  };
100 
101  template <typename R, typename P0, typename P1>
102  struct FunctionSignature<R(P0, P1)> : FunctionSignatureBase<R, 2, P0, P1, EmptyType>
103  {
104  };
105 
106  template <typename R, typename P0, typename P1, typename P2>
107  struct FunctionSignature<R(P0, P1, P2)> : FunctionSignatureBase<R, 3, P0, P1, P2>
108  {
109  };
110 
111 } // namespace detail
112 
113 
116 
119 template <typename T>
120 struct Type
121 {
122  typedef T type;
123 };
124 
127 template <int N>
128 struct Int
129 {
130  static const int value = N;
131 };
132 
138 template <typename Signature>
140 {
141  typedef typename detail::FunctionSignature<Signature>::ResultType Type;
142 };
143 
149 template <typename Signature, std::size_t N>
151 {
152  typedef typename detail::FunctionSignature<Signature>::template Param<N>::Type Type;
153 };
154 
160 template <typename Signature>
162 {
163  static const std::size_t value = detail::FunctionSignature<Signature>::arity;
164 };
165 
166 
174 #define AURORA_ENABLE_IF(...) , typename std::enable_if<__VA_ARGS__>::type* = nullptr
175 
176 
177 #if defined(AURORA_DOXYGEN_SECTION)
178 
190 #define AURORA_REQUIRE_COMPLETE_TYPE(Type) ImplementationDefined
191 
192 #elif defined(__GNUC__) || defined(__clang__)
193 
194  // g++ and clang issue a warning regarding the unused typedef
195  #define AURORA_REQUIRE_COMPLETE_TYPE(Type) typedef char auroraRequireCompleteType[(sizeof(Type))] __attribute__((unused))
196 
197 #else
198 
199  #define AURORA_REQUIRE_COMPLETE_TYPE(Type) typedef char auroraRequireCompleteType[(sizeof(Type))]
200 
201 #endif
202 
203 
212 #define AURORA_AUTO_RETURN(...) decltype(__VA_ARGS__) { return (__VA_ARGS__); }
213 
214 
216 
217 // ---------------------------------------------------------------------------------------------------------------------------
218 
219 
220 namespace detail
221 {
222 
223  // Removes reference and pointer attribute from type
224  template <typename T>
225  struct RemoveIndirection
226  {
227  typedef typename std::remove_pointer<
228  typename std::remove_reference<T>::type
229  >::type type;
230  };
231 
232 
233  // Removes reference, pointer and const attribute from type
234  template <typename T>
235  struct RawType
236  {
237  typedef typename std::remove_const<
238  typename RemoveIndirection<T>::type
239  >::type type;
240  };
241 
242 
243  // Adjusts New such that it has the same const, pointer, reference attributes as Origin
244  template <typename Origin, typename New>
245  struct Replicate
246  {
247  typedef typename RawType<New>::type raw;
248 
249  typedef typename std::conditional<
250  std::is_const<typename RemoveIndirection<Origin>::type>::value,
251  const raw,
252  raw>::type c_qualified;
253 
254  typedef typename std::conditional<std::is_pointer<Origin>::value, c_qualified*, c_qualified>::type cp_qualified;
255  typedef typename std::conditional<std::is_reference<Origin>::value, cp_qualified&, cp_qualified>::type cpr_qualified;
256  typedef typename std::conditional<std::is_const<Origin>::value, const cpr_qualified, cpr_qualified>::type type;
257  };
258 
259  // Human-readable form
260  #define AURORA_REPLICATE(Origin, New) typename aurora::detail::Replicate<Origin, New>::type
261 
262 } // namespace detail
263 } // namespace aurora
264 
265 #endif // AURORA_TEMPLATES_HPP
Simple type wrapper, can be used for overload resolution.
Definition: Templates.hpp:120
Configuration header of the library.
Simple integer wrapper, can be used for overload resolution.
Definition: Templates.hpp:128
Find out the N-th parameter type of a function.
Definition: Templates.hpp:150
Find out the return type of a function.
Definition: Templates.hpp:139
Find out the number of parameters of a function.
Definition: Templates.hpp:161
Definition: DispatchTraits.hpp:39