Horizon
Loading...
Searching...
No Matches
meta_fwd.hpp
Go to the documentation of this file.
1
2//
3// Meta library
4//
5// Copyright Eric Niebler 2014-present
6//
7// Use, modification and distribution is subject to the
8// Boost Software License, Version 1.0. (See accompanying
9// file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11//
12// Project home: https://github.com/ericniebler/meta
13//
14
15#ifndef META_FWD_HPP
16#define META_FWD_HPP
17
18#include <type_traits>
19#include <utility>
20
21#ifdef __clang__
22#pragma GCC diagnostic push
23#pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
24#endif
25
26#define META_CXX_STD_14 201402L
27#define META_CXX_STD_17 201703L
28
29#if defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus // Older clangs define _MSVC_LANG < __cplusplus
30#define META_CXX_VER _MSVC_LANG
31#else
32#define META_CXX_VER __cplusplus
33#endif
34
35#if defined(__apple_build_version__) || defined(__clang__)
36#if defined(__apple_build_version__) || (defined(__clang__) && __clang_major__ < 6)
37#define META_WORKAROUND_LLVM_28385 // https://llvm.org/bugs/show_bug.cgi?id=28385
38#endif
39
40#elif defined(_MSC_VER)
41#define META_HAS_MAKE_INTEGER_SEQ 1
42#if _MSC_VER < 1920
43#define META_WORKAROUND_MSVC_702792 // Bogus C4018 comparing constant expressions with dependent type
44#define META_WORKAROUND_MSVC_703656 // ICE with pack expansion inside decltype in alias template
45#endif
46
47#if _MSC_VER < 1921
48#define META_WORKAROUND_MSVC_756112 // fold expression + alias templates in template argument
49#endif
50
51#elif defined(__GNUC__)
52#define META_WORKAROUND_GCC_86356 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356
53#if __GNUC__ < 8
54#define META_WORKAROUND_GCC_UNKNOWN1 // Older GCCs don't like fold + debug + -march=native
55#endif
56#if __GNUC__ == 5 && __GNUC_MINOR__ == 1
57#define META_WORKAROUND_GCC_66405 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66405
58#endif
59#if __GNUC__ < 5
60#define META_WORKAROUND_CWG_1558 // https://wg21.link/cwg1558
61#endif
62#endif
63
64#ifndef META_CXX_VARIABLE_TEMPLATES
65#ifdef __cpp_variable_templates
66#define META_CXX_VARIABLE_TEMPLATES __cpp_variable_templates
67#else
68#define META_CXX_VARIABLE_TEMPLATES (META_CXX_VER >= META_CXX_STD_14)
69#endif
70#endif
71
72#ifndef META_CXX_INLINE_VARIABLES
73#ifdef __cpp_inline_variables
74#define META_CXX_INLINE_VARIABLES __cpp_inline_variables
75#else
76#define META_CXX_INLINE_VARIABLES (META_CXX_VER >= META_CXX_STD_17)
77#endif
78#endif
79
80#ifndef META_INLINE_VAR
81#if META_CXX_INLINE_VARIABLES
82#define META_INLINE_VAR inline
83#else
84#define META_INLINE_VAR
85#endif
86#endif
87
88#ifndef META_CXX_INTEGER_SEQUENCE
89#ifdef __cpp_lib_integer_sequence
90#define META_CXX_INTEGER_SEQUENCE __cpp_lib_integer_sequence
91#else
92#define META_CXX_INTEGER_SEQUENCE (META_CXX_VER >= META_CXX_STD_14)
93#endif
94#endif
95
96#ifndef META_HAS_MAKE_INTEGER_SEQ
97#ifdef __has_builtin
98#if __has_builtin(__make_integer_seq)
99#define META_HAS_MAKE_INTEGER_SEQ 1
100#endif
101#endif
102#endif
103#ifndef META_HAS_MAKE_INTEGER_SEQ
104#define META_HAS_MAKE_INTEGER_SEQ 0
105#endif
106
107#ifndef META_HAS_TYPE_PACK_ELEMENT
108#ifdef __has_builtin
109#if __has_builtin(__type_pack_element)
110#define META_HAS_TYPE_PACK_ELEMENT 1
111#endif
112#endif
113#endif
114#ifndef META_HAS_TYPE_PACK_ELEMENT
115#define META_HAS_TYPE_PACK_ELEMENT 0
116#endif
117
118#if !defined(META_DEPRECATED) && !defined(META_DISABLE_DEPRECATED_WARNINGS)
119#if defined(__cpp_attribute_deprecated) || META_CXX_VER >= META_CXX_STD_14
120#define META_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]
121#elif defined(__clang__) || defined(__GNUC__)
122#define META_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__)))
123#endif
124#endif
125#ifndef META_DEPRECATED
126#define META_DEPRECATED(...)
127#endif
128
129#ifndef META_CXX_FOLD_EXPRESSIONS
130#ifdef __cpp_fold_expressions
131#define META_CXX_FOLD_EXPRESSIONS __cpp_fold_expressions
132#else
133#define META_CXX_FOLD_EXPRESSIONS (META_CXX_VER >= META_CXX_STD_17)
134#endif
135#endif
136
137#if META_CXX_FOLD_EXPRESSIONS
138#if !META_CXX_VARIABLE_TEMPLATES
139#error Fold expressions, but no variable templates?
140#endif
141#endif
142
143#if (defined(__cpp_concepts) && __cpp_concepts > 0) || defined(META_DOXYGEN_INVOKED)
144#if !META_CXX_VARIABLE_TEMPLATES
145#error Concepts, but no variable templates?
146#endif
147#if __cpp_concepts <= 201507L && !defined(META_DOXYGEN_INVOKED)
148#define META_CONCEPT concept bool
149// TS concepts subsumption barrier for atomic expressions
150#define META_CONCEPT_BARRIER(...) ::meta::detail::barrier<__VA_ARGS__>
151#define META_TYPE_CONSTRAINT(...) typename
152#else
153#define META_CONCEPT concept
154#define META_CONCEPT_BARRIER(...) __VA_ARGS__
155#define META_TYPE_CONSTRAINT(...) __VA_ARGS__
156#endif
157#else
158#define META_TYPE_CONSTRAINT(...) typename
159#endif
160
161#if (defined(__cpp_lib_type_trait_variable_templates) && \
162 __cpp_lib_type_trait_variable_templates > 0)
163#define META_CXX_TRAIT_VARIABLE_TEMPLATES 1
164#else
165#define META_CXX_TRAIT_VARIABLE_TEMPLATES 0
166#endif
167
168#if defined(__clang__)
169#define META_IS_SAME(...) __is_same(__VA_ARGS__)
170#elif defined(__GNUC__) && __GNUC__ >= 6
171#define META_IS_SAME(...) __is_same_as(__VA_ARGS__)
172#elif META_CXX_TRAIT_VARIABLE_TEMPLATES
173#define META_IS_SAME(...) std::is_same_v<__VA_ARGS__>
174#else
175#define META_IS_SAME(...) std::is_same<__VA_ARGS__>::value
176#endif
177
178#if defined(__GNUC__) || defined(_MSC_VER)
179#define META_IS_BASE_OF(...) __is_base_of(__VA_ARGS__)
180#elif META_CXX_TRAIT_VARIABLE_TEMPLATES
181#define META_IS_BASE_OF(...) std::is_base_of_v<__VA_ARGS__>
182#else
183#define META_IS_BASE_OF(...) std::is_base_of<__VA_ARGS__>::value
184#endif
185
186#if defined(__clang__) || defined(_MSC_VER) || \
187 (defined(__GNUC__) && __GNUC__ >= 8)
188#define META_IS_CONSTRUCTIBLE(...) __is_constructible(__VA_ARGS__)
189#elif META_CXX_TRAIT_VARIABLE_TEMPLATES
190#define META_IS_CONSTRUCTIBLE(...) std::is_constructible_v<__VA_ARGS__>
191#else
192#define META_IS_CONSTRUCTIBLE(...) std::is_constructible<__VA_ARGS__>::value
193#endif
194
196// Non-portable forward declarations of standard containers
197#ifdef _LIBCPP_VERSION
198#define META_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
199#define META_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
200#elif defined(_MSVC_STL_VERSION)
201#define META_BEGIN_NAMESPACE_STD _STD_BEGIN
202#define META_END_NAMESPACE_STD _STD_END
203#else
204#define META_BEGIN_NAMESPACE_STD namespace std {
205#define META_END_NAMESPACE_STD }
206#endif
207
208#if defined(__GLIBCXX__)
209#define META_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_VERSION
210#define META_END_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION
211#define META_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
212#define META_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_CONTAINER
213#else
214#define META_BEGIN_NAMESPACE_VERSION
215#define META_END_NAMESPACE_VERSION
216#define META_BEGIN_NAMESPACE_CONTAINER
217#define META_END_NAMESPACE_CONTAINER
218#endif
219
220#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 4000
221#define META_TEMPLATE_VIS _LIBCPP_TEMPLATE_VIS
222#elif defined(_LIBCPP_VERSION)
223#define META_TEMPLATE_VIS _LIBCPP_TYPE_VIS_ONLY
224#else
225#define META_TEMPLATE_VIS
226#endif
228
229namespace meta
230{
231#if META_CXX_INTEGER_SEQUENCE
232 using std::integer_sequence;
233#else
234 template <typename T, T...>
235 struct integer_sequence;
236#endif
237
238 template <typename... Ts>
239 struct list;
240
241 template <typename T>
242 struct id;
243
244 template <template <typename...> class>
245 struct quote;
246
247 template <typename T, template <T...> class F>
248 struct quote_i;
249
250 template <template <typename...> class C, typename... Ts>
251 struct defer;
252
253 template <typename T, template <T...> class C, T... Is>
254 struct defer_i;
255
256#if META_CXX_VARIABLE_TEMPLATES || defined(META_DOXYGEN_INVOKED)
261 template <typename, template <typename...> class>
262 META_INLINE_VAR constexpr bool is_v = false;
263 template <typename... Ts, template <typename...> class C>
264 META_INLINE_VAR constexpr bool is_v<C<Ts...>, C> = true;
265#endif
266
267#ifdef META_CONCEPT
268 namespace detail
269 {
270 template <bool B>
271 META_INLINE_VAR constexpr bool barrier = B;
272
273 template <class T, T> struct require_constant; // not defined
274 }
275
276 template <typename...>
277 META_CONCEPT is_true = META_CONCEPT_BARRIER(true);
278
279 template <typename T, typename U>
280 META_CONCEPT same_as =
281 META_CONCEPT_BARRIER(META_IS_SAME(T, U));
282
283 template <template <typename...> class C, typename... Ts>
284 META_CONCEPT valid = requires
285 {
286 typename C<Ts...>;
287 };
288
289 template <typename T, template <T...> class C, T... Is>
290 META_CONCEPT valid_i = requires
291 {
292 typename C<Is...>;
293 };
294
295 template <typename T>
296 META_CONCEPT trait = requires
297 {
298 typename T::type;
299 };
300
301 template <typename T>
302 META_CONCEPT invocable = requires
303 {
304 typename quote<T::template invoke>;
305 };
306
307 template <typename T>
308 META_CONCEPT list_like = is_v<T, list>;
309
310 // clang-format off
311 template <typename T>
312 META_CONCEPT integral = requires
313 {
314 typename T::type;
315 typename T::value_type;
316 typename T::type::value_type;
317 }
318 && same_as<typename T::value_type, typename T::type::value_type>
319#if META_CXX_TRAIT_VARIABLE_TEMPLATES
320 && std::is_integral_v<typename T::value_type>
321#else
322 && std::is_integral<typename T::value_type>::value
323#endif
324
325 && requires
326 {
327 // { T::value } -> same_as<const typename T::value_type&>;
328 T::value;
329 requires same_as<decltype(T::value), const typename T::value_type>;
330 typename detail::require_constant<decltype(T::value), T::value>;
331
332 // { T::type::value } -> same_as<const typename T::value_type&>;
333 T::type::value;
334 requires same_as<decltype(T::type::value), const typename T::value_type>;
335 typename detail::require_constant<decltype(T::type::value), T::type::value>;
336 requires T::value == T::type::value;
337
338 // { T{}() } -> same_as<typename T::value_type>;
339 T{}();
340 requires same_as<decltype(T{}()), typename T::value_type>;
341 typename detail::require_constant<decltype(T{}()), T{}()>;
342 requires T{}() == T::value;
343
344 // { T{} } -> typename T::value_type;
345 };
346 // clang-format on
347#endif // META_CONCEPT
348
349 namespace extension
350 {
351 template <META_TYPE_CONSTRAINT(invocable) F, typename L>
352 struct apply;
353 }
354} // namespace meta
355
356#ifdef __clang__
357#pragma GCC diagnostic pop
358#endif
359
360#endif
_t< extension::apply< Fn, L > > apply
Applies the invocable Fn using the types in the type list L as arguments.
Definition meta.hpp:1030
defer< id, T > id
Definition meta.hpp:585
Tiny metaprogramming library.
Definition meta.hpp:116