1 // Range v3 library
2 //
3 //  Copyright Eric Niebler 2013-present
4 //  Copyright Casey Carter 2016
5 //
6 //  Use, modification and distribution is subject to the
7 //  Boost Software License, Version 1.0. (See accompanying
8 //  file LICENSE_1_0.txt or copy at
9 //  http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 
14 #ifndef RANGES_V3_DETAIL_CONFIG_HPP
15 #define RANGES_V3_DETAIL_CONFIG_HPP
16 
17 // Grab some version information.
18 #ifndef __has_include
19 #include <iosfwd>
20 #elif __has_include(<version>)
21 #include <version>
22 #else
23 #include <iosfwd>
24 #endif
25 
26 #if(defined(NDEBUG) && !defined(RANGES_ENSURE_MSG)) || \
27     (!defined(NDEBUG) && !defined(RANGES_ASSERT) &&    \
28      ((defined(__GNUC__) && !defined(__clang__) &&     \
29        (__GNUC__ < 5 || defined(__MINGW32__))) ||      \
30       defined(_MSVC_STL_VERSION)))
31 #include <cstdio>
32 #include <cstdlib>
33 
34 namespace ranges
35 {
36     namespace detail
37     {
38         template<typename = void>
assert_failure(char const * file,int line,char const * msg)39         [[noreturn]] void assert_failure(char const * file, int line, char const * msg)
40         {
41             std::fprintf(stderr, "%s(%d): %s\n", file, line, msg);
42             std::abort();
43         }
44     } // namespace detail
45 } // namespace ranges
46 
47 #endif
48 
49 #ifndef RANGES_ASSERT
50 // Always use our hand-rolled assert implementation on older GCCs, which do
51 // not allow assert to be used in a constant expression, and on MSVC whose
52 // assert is not marked [[noreturn]].
53 #if !defined(NDEBUG) && ((defined(__GNUC__) && !defined(__clang__) && \
54                           (__GNUC__ < 5 || defined(__MINGW32__))) ||  \
55                          defined(_MSVC_STL_VERSION))
56 #define RANGES_ASSERT(...)                                    \
57     static_cast<void>((__VA_ARGS__)                           \
58                           ? void(0)                           \
59                           : ::ranges::detail::assert_failure( \
60                                 __FILE__, __LINE__, "assertion failed: " #__VA_ARGS__))
61 #else
62 #include <cassert>
63 #define RANGES_ASSERT assert
64 #endif
65 #endif
66 
67 #include <meta/meta_fwd.hpp>
68 
69 #ifndef RANGES_ASSUME
70 #if defined(__clang__) || defined(__GNUC__)
71 #define RANGES_ASSUME(COND) static_cast<void>((COND) ? void(0) : __builtin_unreachable())
72 #elif defined(_MSC_VER)
73 #define RANGES_ASSUME(COND) static_cast<void>(__assume(COND))
74 #else
75 #define RANGES_ASSUME(COND) static_cast<void>(COND)
76 #endif
77 #endif // RANGES_ASSUME
78 
79 #ifndef RANGES_EXPECT
80 #ifdef NDEBUG
81 #define RANGES_EXPECT(COND) RANGES_ASSUME(COND)
82 #else // NDEBUG
83 #define RANGES_EXPECT(COND) RANGES_ASSERT(COND)
84 #endif // NDEBUG
85 #endif // RANGES_EXPECT
86 
87 #ifndef RANGES_ENSURE_MSG
88 #if defined(NDEBUG)
89 #define RANGES_ENSURE_MSG(COND, MSG)                             \
90     static_cast<void>((COND) ? void(0)                           \
91                              : ::ranges::detail::assert_failure( \
92                                    __FILE__, __LINE__, "ensure failed: " MSG))
93 #else
94 #define RANGES_ENSURE_MSG(COND, MSG) RANGES_ASSERT((COND) && MSG)
95 #endif
96 #endif
97 
98 #ifndef RANGES_ENSURE
99 #define RANGES_ENSURE(...) RANGES_ENSURE_MSG((__VA_ARGS__), #__VA_ARGS__)
100 #endif
101 
102 #define RANGES_DECLTYPE_AUTO_RETURN(...) \
103     ->decltype(__VA_ARGS__)              \
104     {                                    \
105         return (__VA_ARGS__);            \
106     }                                    \
107     /**/
108 
109 #define RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT(...)                                 \
110     noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__)))->decltype(__VA_ARGS__) \
111     {                                                                             \
112         return (__VA_ARGS__);                                                     \
113     }                                                                             \
114     /**/
115 
116 #define RANGES_AUTO_RETURN_NOEXCEPT(...)                   \
117     noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) \
118     {                                                      \
119         return (__VA_ARGS__);                              \
120     }                                                      \
121     /**/
122 
123 #define RANGES_DECLTYPE_NOEXCEPT(...) \
124     noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__)))->decltype(__VA_ARGS__) /**/
125 
126 // Non-portable forward declarations of standard containers
127 #define RANGES_BEGIN_NAMESPACE_STD META_BEGIN_NAMESPACE_STD
128 #define RANGES_END_NAMESPACE_STD META_END_NAMESPACE_STD
129 #define RANGES_BEGIN_NAMESPACE_VERSION META_BEGIN_NAMESPACE_VERSION
130 #define RANGES_END_NAMESPACE_VERSION META_END_NAMESPACE_VERSION
131 #define RANGES_BEGIN_NAMESPACE_CONTAINER META_BEGIN_NAMESPACE_CONTAINER
132 #define RANGES_END_NAMESPACE_CONTAINER META_END_NAMESPACE_CONTAINER
133 
134 // Database of feature versions
135 #define RANGES_CXX_STATIC_ASSERT_11 200410L
136 #define RANGES_CXX_STATIC_ASSERT_14 RANGES_CXX_STATIC_ASSERT_11
137 #define RANGES_CXX_STATIC_ASSERT_17 201411L
138 #define RANGES_CXX_VARIABLE_TEMPLATES_11 0L
139 #define RANGES_CXX_VARIABLE_TEMPLATES_14 201304L
140 #define RANGES_CXX_VARIABLE_TEMPLATES_17 RANGES_CXX_VARIABLE_TEMPLATES_14
141 #define RANGES_CXX_ATTRIBUTE_DEPRECATED_11 0L
142 #define RANGES_CXX_ATTRIBUTE_DEPRECATED_14 201309L
143 #define RANGES_CXX_ATTRIBUTE_DEPRECATED_17 RANGES_CXX_ATTRIBUTE_DEPRECATED_14
144 #define RANGES_CXX_CONSTEXPR_11 200704L
145 #define RANGES_CXX_CONSTEXPR_14 201304L
146 #define RANGES_CXX_CONSTEXPR_17 201603L
147 #define RANGES_CXX_CONSTEXPR_LAMBDAS 201603L
148 #define RANGES_CXX_RANGE_BASED_FOR_11 200907L
149 #define RANGES_CXX_RANGE_BASED_FOR_14 RANGES_CXX_RANGE_BASED_FOR_11
150 #define RANGES_CXX_RANGE_BASED_FOR_17 201603L
151 #define RANGES_CXX_LIB_IS_FINAL_11 0L
152 #define RANGES_CXX_LIB_IS_FINAL_14 201402L
153 #define RANGES_CXX_LIB_IS_FINAL_17 RANGES_CXX_LIB_IS_FINAL_14
154 #define RANGES_CXX_RETURN_TYPE_DEDUCTION_11 0L
155 #define RANGES_CXX_RETURN_TYPE_DEDUCTION_14 201304L
156 #define RANGES_CXX_RETURN_TYPE_DEDUCTION_17 RANGES_CXX_RETURN_TYPE_DEDUCTION_14
157 #define RANGES_CXX_GENERIC_LAMBDAS_11 0L
158 #define RANGES_CXX_GENERIC_LAMBDAS_14 201304L
159 #define RANGES_CXX_GENERIC_LAMBDAS_17 RANGES_CXX_GENERIC_LAMBDAS_14
160 #define RANGES_CXX_STD_11 201103L
161 #define RANGES_CXX_STD_14 201402L
162 #define RANGES_CXX_STD_17 201703L
163 #define RANGES_CXX_THREAD_LOCAL_PRE_STANDARD \
164     200000L // Arbitrary number between 0 and C++11
165 #define RANGES_CXX_THREAD_LOCAL_11 RANGES_CXX_STD_11
166 #define RANGES_CXX_THREAD_LOCAL_14 RANGES_CXX_THREAD_LOCAL_11
167 #define RANGES_CXX_THREAD_LOCAL_17 RANGES_CXX_THREAD_LOCAL_14
168 #define RANGES_CXX_INLINE_VARIABLES_11 0L
169 #define RANGES_CXX_INLINE_VARIABLES_14 0L
170 #define RANGES_CXX_INLINE_VARIABLES_17 201606L
171 #define RANGES_CXX_COROUTINES_11 0L
172 #define RANGES_CXX_COROUTINES_14 0L
173 #define RANGES_CXX_COROUTINES_17 0L
174 #define RANGES_CXX_COROUTINES_TS1 201703L
175 #define RANGES_CXX_DEDUCTION_GUIDES_11 0L
176 #define RANGES_CXX_DEDUCTION_GUIDES_14 0L
177 #define RANGES_CXX_DEDUCTION_GUIDES_17 201606L
178 #define RANGES_CXX_IF_CONSTEXPR_11 0L
179 #define RANGES_CXX_IF_CONSTEXPR_14 0L
180 #define RANGES_CXX_IF_CONSTEXPR_17 201606L
181 #define RANGES_CXX_ALIGNED_NEW_11 0L
182 #define RANGES_CXX_ALIGNED_NEW_14 0L
183 #define RANGES_CXX_ALIGNED_NEW_17 201606L
184 
185 // Implementation-specific diagnostic control
186 #if defined(_MSC_VER) && !defined(__clang__)
187 #define RANGES_DIAGNOSTIC_PUSH __pragma(warning(push))
188 #define RANGES_DIAGNOSTIC_POP __pragma(warning(pop))
189 #define RANGES_DIAGNOSTIC_IGNORE_PRAGMAS __pragma(warning(disable : 4068))
190 #define RANGES_DIAGNOSTIC_IGNORE(X) \
191     RANGES_DIAGNOSTIC_IGNORE_PRAGMAS __pragma(warning(disable : X))
192 #define RANGES_DIAGNOSTIC_IGNORE_SHADOWING RANGES_DIAGNOSTIC_IGNORE(4456)
193 #define RANGES_DIAGNOSTIC_IGNORE_INDENTATION
194 #define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
195 #define RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS RANGES_DIAGNOSTIC_IGNORE(4099)
196 #define RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
197 #define RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
198 #define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_INTERNAL
199 #define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
200 #define RANGES_DIAGNOSTIC_IGNORE_ZERO_LENGTH_ARRAY
201 #define RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
202 #define RANGES_DIAGNOSTIC_IGNORE_CXX2A_COMPAT
203 #define RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
204 #define RANGES_DIAGNOSTIC_IGNORE_MISSING_BRACES
205 #define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE
206 #define RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
207 #define RANGES_DIAGNOSTIC_IGNORE_RANGE_LOOP_ANALYSIS
208 #define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS RANGES_DIAGNOSTIC_IGNORE(4996)
209 #define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_THIS_CAPTURE
210 #define RANGES_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
211 // Ignores both "divide by zero" and "mod by zero":
212 #define RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO RANGES_DIAGNOSTIC_IGNORE(4723 4724)
213 #define RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH RANGES_DIAGNOSTIC_IGNORE(4146)
214 #define RANGES_DIAGNOSTIC_IGNORE_TRUNCATION RANGES_DIAGNOSTIC_IGNORE(4244)
215 #define RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS \
216     RANGES_DIAGNOSTIC_IGNORE(4522)
217 #define RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE
218 #define RANGES_DIAGNOSTIC_KEYWORD_MACRO
219 
220 #define RANGES_CXX_VER _MSVC_LANG
221 
222 #if _MSC_VER < 1920 || _MSVC_LANG < 201703L
223 #error range-v3 requires Visual Studio 2019 with the /std:c++17 (or /std:c++latest) and /permissive- options.
224 #endif
225 
226 #if _MSC_VER < 1927
227 #define RANGES_WORKAROUND_MSVC_895622 // Error when phase 1 name binding finds only
228                                       // deleted function
229 
230 #if _MSC_VER < 1925
231 #define RANGES_WORKAROUND_MSVC_779708 // ADL for operands of function type [No workaround]
232 
233 #if _MSC_VER < 1923
234 #define RANGES_WORKAROUND_MSVC_573728 // rvalues of array types bind to lvalue references
235                                       // [no workaround]
236 #define RANGES_WORKAROUND_MSVC_934330 // Deduction guide not correctly preferred to copy
237                                       // deduction candidate [No workaround]
238 
239 #if _MSC_VER < 1922
240 #define RANGES_WORKAROUND_MSVC_756601 // constexpr friend non-template erroneously
241                                       // rejected with C3615
242 #define RANGES_WORKAROUND_MSVC_793042 // T[0] sometimes accepted as a valid type in SFINAE
243                                       // context
244 
245 #if _MSC_VER < 1921
246 #define RANGES_WORKAROUND_MSVC_785522 // SFINAE failure for error in immediate context
247 #define RANGES_WORKAROUND_MSVC_786376 // Assertion casting anonymous union member in
248                                       // trailing-return-type
249 #define RANGES_WORKAROUND_MSVC_787074 // Over-eager substitution of dependent type in
250                                       // non-instantiated nested class template
251 #define RANGES_WORKAROUND_MSVC_790554 // Assert for return type that uses dependent
252                                       // default non-type template argument
253 #endif                                // _MSC_VER < 1921
254 #endif                                // _MSC_VER < 1922
255 #endif                                // _MSC_VER < 1923
256 #endif                                // _MSC_VER < 1925
257 #endif                                // _MSC_VER < 1926
258 
259 #if 1 // Fixed in 1920, but more bugs hiding behind workaround
260 #define RANGES_WORKAROUND_MSVC_701385 // Yet another alias expansion error
261 #endif
262 
263 #define RANGES_WORKAROUND_MSVC_249830 // constexpr and arguments that aren't subject to
264                                       // lvalue-to-rvalue conversion
265 #define RANGES_WORKAROUND_MSVC_677925 // Bogus C2676 "binary '++': '_Ty' does not define
266                                       // this operator"
267 #define RANGES_WORKAROUND_MSVC_683388 // decltype(*i) is incorrectly an rvalue reference
268                                       // for pointer-to-array i
269 #define RANGES_WORKAROUND_MSVC_688606 // SFINAE failing to account for access control
270                                       // during specialization matching
271 #define RANGES_WORKAROUND_MSVC_786312 // Yet another mixed-pack-expansion failure
272 #define RANGES_WORKAROUND_MSVC_792338 // Failure to match specialization enabled via call
273                                       // to constexpr function
274 #define RANGES_WORKAROUND_MSVC_835948 // Silent bad codegen destroying sized_generator [No
275                                       // workaround]
276 #define RANGES_WORKAROUND_MSVC_934264 // Explicitly-defaulted inherited default
277                                       // constructor is not correctly implicitly constexpr
278 #if _MSVC_LANG <= 201703L
279 #define RANGES_WORKAROUND_MSVC_OLD_LAMBDA
280 #endif
281 
282 #elif defined(__GNUC__) || defined(__clang__)
283 #define RANGES_PRAGMA(X) _Pragma(#X)
284 #define RANGES_DIAGNOSTIC_PUSH RANGES_PRAGMA(GCC diagnostic push)
285 #define RANGES_DIAGNOSTIC_POP RANGES_PRAGMA(GCC diagnostic pop)
286 #define RANGES_DIAGNOSTIC_IGNORE_PRAGMAS RANGES_PRAGMA(GCC diagnostic ignored "-Wpragmas")
287 #define RANGES_DIAGNOSTIC_IGNORE(X)                                  \
288     RANGES_DIAGNOSTIC_IGNORE_PRAGMAS                                 \
289     RANGES_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas")        \
290     RANGES_PRAGMA(GCC diagnostic ignored "-Wunknown-warning-option") \
291     RANGES_PRAGMA(GCC diagnostic ignored X)
292 #define RANGES_DIAGNOSTIC_IGNORE_SHADOWING RANGES_DIAGNOSTIC_IGNORE("-Wshadow")
293 #define RANGES_DIAGNOSTIC_IGNORE_INDENTATION \
294     RANGES_DIAGNOSTIC_IGNORE("-Wmisleading-indentation")
295 #define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL \
296     RANGES_DIAGNOSTIC_IGNORE("-Wundefined-internal")
297 #define RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS \
298     RANGES_DIAGNOSTIC_IGNORE("-Wmismatched-tags")
299 #define RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION \
300     RANGES_DIAGNOSTIC_IGNORE("-Wsign-conversion")
301 #define RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL RANGES_DIAGNOSTIC_IGNORE("-Wfloat-equal")
302 #define RANGES_DIAGNOSTIC_IGNORE_MISSING_BRACES \
303     RANGES_DIAGNOSTIC_IGNORE("-Wmissing-braces")
304 #define RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS \
305     RANGES_DIAGNOSTIC_IGNORE("-Wglobal-constructors")
306 #define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_INTERNAL \
307     RANGES_DIAGNOSTIC_IGNORE("-Wunneeded-internal-declaration")
308 #define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER \
309     RANGES_DIAGNOSTIC_IGNORE("-Wunneeded-member-function")
310 #define RANGES_DIAGNOSTIC_IGNORE_ZERO_LENGTH_ARRAY \
311     RANGES_DIAGNOSTIC_IGNORE("-Wzero-length-array")
312 #define RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT RANGES_DIAGNOSTIC_IGNORE("-Wc++1z-compat")
313 #define RANGES_DIAGNOSTIC_IGNORE_CXX2A_COMPAT RANGES_DIAGNOSTIC_IGNORE("-Wc++2a-compat")
314 #define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE \
315     RANGES_DIAGNOSTIC_IGNORE("-Wundefined-func-template")
316 #define RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE \
317     RANGES_DIAGNOSTIC_IGNORE("-Winconsistent-missing-override")
318 #define RANGES_DIAGNOSTIC_IGNORE_RANGE_LOOP_ANALYSIS \
319     RANGES_DIAGNOSTIC_IGNORE("-Wrange-loop-analysis")
320 #define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS \
321     RANGES_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations")
322 #define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_THIS_CAPTURE \
323     RANGES_DIAGNOSTIC_IGNORE("-Wdeprecated-this-capture")
324 #define RANGES_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME \
325     RANGES_DIAGNOSTIC_IGNORE("-Winit-list-lifetime")
326 #define RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO
327 #define RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
328 #define RANGES_DIAGNOSTIC_IGNORE_TRUNCATION
329 #define RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS
330 #define RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE \
331     RANGES_DIAGNOSTIC_IGNORE("-Wvoid-ptr-dereference")
332 #define RANGES_DIAGNOSTIC_KEYWORD_MACRO RANGES_DIAGNOSTIC_IGNORE("-Wkeyword-macro")
333 
334 #define RANGES_WORKAROUND_CWG_1554
335 #ifdef __clang__
336 #if __clang_major__ < 4
337 #define RANGES_WORKAROUND_CLANG_23135 // constexpr leads to premature instantiation on
338                                       // clang-3.x
339 #endif
340 #define RANGES_WORKAROUND_CLANG_43400 // template friend is redefinition of itself
341 #else                                 // __GNUC__
342 #if __GNUC__ < 6
343 #define RANGES_WORKAROUND_GCC_UNFILED0 /* Workaround old GCC name lookup bug */
344 #endif
345 #if __GNUC__ == 7 || __GNUC__ == 8
346 #define RANGES_WORKAROUND_GCC_91525 /* Workaround strange GCC ICE */
347 #endif
348 #if __GNUC__ >= 9
349 #if __GNUC__ == 9 && __GNUC_MINOR__ < 3 && __cplusplus == RANGES_CXX_STD_17
350 #define RANGES_WORKAROUND_GCC_91923 // Failure-to-SFINAE with class type NTTP in C++17
351 #endif
352 #endif
353 #endif
354 
355 #else
356 #define RANGES_DIAGNOSTIC_PUSH
357 #define RANGES_DIAGNOSTIC_POP
358 #define RANGES_DIAGNOSTIC_IGNORE_PRAGMAS
359 #define RANGES_DIAGNOSTIC_IGNORE_SHADOWING
360 #define RANGES_DIAGNOSTIC_IGNORE_INDENTATION
361 #define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
362 #define RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
363 #define RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
364 #define RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
365 #define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_INTERNAL
366 #define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
367 #define RANGES_DIAGNOSTIC_IGNORE_ZERO_LENGTH_ARRAY
368 #define RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
369 #define RANGES_DIAGNOSTIC_IGNORE_CXX2A_COMPAT
370 #define RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
371 #define RANGES_DIAGNOSTIC_IGNORE_MISSING_BRACES
372 #define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE
373 #define RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
374 #define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
375 #define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_THIS_CAPTURE
376 #define RANGES_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
377 #define RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO
378 #define RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
379 #define RANGES_DIAGNOSTIC_IGNORE_TRUNCATION
380 #define RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS
381 #define RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE
382 #define RANGES_DIAGNOSTIC_KEYWORD_MACRO
383 #endif
384 
385 // Configuration via feature-test macros, with fallback to __cplusplus
386 #ifndef RANGES_CXX_VER
387 #define RANGES_CXX_VER __cplusplus
388 #endif
389 
390 #define RANGES_CXX_FEATURE_CONCAT2(y, z) RANGES_CXX_##y##_##z
391 #define RANGES_CXX_FEATURE_CONCAT(y, z) RANGES_CXX_FEATURE_CONCAT2(y, z)
392 
393 #if RANGES_CXX_VER >= RANGES_CXX_STD_17
394 #define RANGES_CXX_STD RANGES_CXX_STD_17
395 #define RANGES_CXX_FEATURE(x) RANGES_CXX_FEATURE_CONCAT(x, 17)
396 #elif RANGES_CXX_VER >= RANGES_CXX_STD_14
397 #define RANGES_CXX_STD RANGES_CXX_STD_14
398 #define RANGES_CXX_FEATURE(x) RANGES_CXX_FEATURE_CONCAT(x, 14)
399 #else
400 #define RANGES_CXX_STD RANGES_CXX_STD_11
401 #define RANGES_CXX_FEATURE(x) RANGES_CXX_FEATURE_CONCAT(x, 11)
402 #endif
403 
404 #ifndef RANGES_CXX_STATIC_ASSERT
405 #ifdef __cpp_static_assert
406 #define RANGES_CXX_STATIC_ASSERT __cpp_static_assert
407 #else
408 #define RANGES_CXX_STATIC_ASSERT RANGES_CXX_FEATURE(STATIC_ASSERT)
409 #endif
410 #endif
411 
412 #ifndef RANGES_CXX_VARIABLE_TEMPLATES
413 #ifdef __cpp_variable_templates
414 #define RANGES_CXX_VARIABLE_TEMPLATES __cpp_variable_templates
415 #else
416 #define RANGES_CXX_VARIABLE_TEMPLATES RANGES_CXX_FEATURE(VARIABLE_TEMPLATES)
417 #endif
418 #endif
419 
420 #if(defined(__cpp_lib_type_trait_variable_templates) && \
421     __cpp_lib_type_trait_variable_templates > 0) ||     \
422     RANGES_CXX_VER >= RANGES_CXX_STD_17
423 #define RANGES_CXX_TRAIT_VARIABLE_TEMPLATES 1
424 #else
425 #define RANGES_CXX_TRAIT_VARIABLE_TEMPLATES 0
426 #endif
427 
428 #ifndef RANGES_CXX_ATTRIBUTE_DEPRECATED
429 #ifdef __has_cpp_attribute
430 #define RANGES_CXX_ATTRIBUTE_DEPRECATED __has_cpp_attribute(deprecated)
431 #elif defined(__cpp_attribute_deprecated)
432 #define RANGES_CXX_ATTRIBUTE_DEPRECATED __cpp_attribute_deprecated
433 #else
434 #define RANGES_CXX_ATTRIBUTE_DEPRECATED RANGES_CXX_FEATURE(ATTRIBUTE_DEPRECATED)
435 #endif
436 #endif
437 
438 #ifndef RANGES_CXX_CONSTEXPR
439 #ifdef __cpp_constexpr
440 #define RANGES_CXX_CONSTEXPR __cpp_constexpr
441 #else
442 #define RANGES_CXX_CONSTEXPR RANGES_CXX_FEATURE(CONSTEXPR)
443 #endif
444 #endif
445 
446 #ifndef RANGES_CXX_RANGE_BASED_FOR
447 #ifdef __cpp_range_based_for
448 #define RANGES_CXX_RANGE_BASED_FOR __cpp_range_based_for
449 #else
450 #define RANGES_CXX_RANGE_BASED_FOR RANGES_CXX_FEATURE(RANGE_BASED_FOR)
451 #endif
452 #endif
453 
454 #ifndef RANGES_CXX_LIB_IS_FINAL
455 #include <type_traits>
456 #ifdef __cpp_lib_is_final
457 #define RANGES_CXX_LIB_IS_FINAL __cpp_lib_is_final
458 #else
459 #define RANGES_CXX_LIB_IS_FINAL RANGES_CXX_FEATURE(LIB_IS_FINAL)
460 #endif
461 #endif
462 
463 #ifndef RANGES_CXX_RETURN_TYPE_DEDUCTION
464 #ifdef __cpp_return_type_deduction
465 #define RANGES_CXX_RETURN_TYPE_DEDUCTION __cpp_return_type_deduction
466 #else
467 #define RANGES_CXX_RETURN_TYPE_DEDUCTION RANGES_CXX_FEATURE(RETURN_TYPE_DEDUCTION)
468 #endif
469 #endif
470 
471 #ifndef RANGES_CXX_GENERIC_LAMBDAS
472 #ifdef __cpp_generic_lambdas
473 #define RANGES_CXX_GENERIC_LAMBDAS __cpp_generic_lambdas
474 #else
475 #define RANGES_CXX_GENERIC_LAMBDAS RANGES_CXX_FEATURE(GENERIC_LAMBDAS)
476 #endif
477 #endif
478 
479 #ifndef RANGES_CXX_THREAD_LOCAL
480 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED <= 70100
481 #define RANGES_CXX_THREAD_LOCAL 0
482 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) || \
483     (defined(__clang__) && (defined(__CYGWIN__) || defined(__apple_build_version__)))
484 // BUGBUG avoid unresolved __cxa_thread_atexit
485 #define RANGES_CXX_THREAD_LOCAL RANGES_CXX_THREAD_LOCAL_PRE_STANDARD
486 #else
487 #define RANGES_CXX_THREAD_LOCAL RANGES_CXX_FEATURE(THREAD_LOCAL)
488 #endif
489 #endif
490 
491 #if !defined(RANGES_DEPRECATED) && !defined(RANGES_DISABLE_DEPRECATED_WARNINGS)
492 #if defined(__GNUC__) && !defined(__clang__)
493 // GCC's support for [[deprecated("message")]] is unusably buggy.
494 #define RANGES_DEPRECATED(MSG) __attribute__((deprecated(MSG)))
495 #elif RANGES_CXX_ATTRIBUTE_DEPRECATED && \
496     !((defined(__clang__) || defined(__GNUC__)) && RANGES_CXX_STD < RANGES_CXX_STD_14)
497 #define RANGES_DEPRECATED(MSG) [[deprecated(MSG)]]
498 #elif defined(__clang__) || defined(__GNUC__)
499 #define RANGES_DEPRECATED(MSG) __attribute__((deprecated(MSG)))
500 #endif
501 #endif
502 #ifndef RANGES_DEPRECATED
503 #define RANGES_DEPRECATED(MSG)
504 #endif
505 
506 #if !defined(RANGES_DEPRECATED_HEADER) && !defined(RANGES_DISABLE_DEPRECATED_WARNINGS)
507 #ifdef __GNUC__
508 #define RANGES_DEPRECATED_HEADER(MSG) RANGES_PRAGMA(GCC warning MSG)
509 #elif defined(_MSC_VER)
510 #define RANGES_STRINGIZE_(MSG) #MSG
511 #define RANGES_STRINGIZE(MSG) RANGES_STRINGIZE_(MSG)
512 #define RANGES_DEPRECATED_HEADER(MSG) \
513     __pragma(message(__FILE__ "(" RANGES_STRINGIZE(__LINE__) ") : Warning: " MSG))
514 #endif
515 #else
516 #define RANGES_DEPRECATED_HEADER(MSG) /**/
517 #endif
518 // #ifndef RANGES_DEPRECATED_HEADER
519 // #define RANGES_DEPRECATED_HEADER(MSG)
520 // #endif
521 
522 #ifndef RANGES_CXX_COROUTINES
523 #if defined(__cpp_coroutines) && defined(__has_include)
524 #if __has_include(<coroutine>)
525 #define RANGES_CXX_COROUTINES __cpp_coroutines
526 #define RANGES_COROUTINES_HEADER <coroutine>
527 #define RANGES_COROUTINES_NS std
528 #elif __has_include(<experimental/coroutine>)
529 #define RANGES_CXX_COROUTINES __cpp_coroutines
530 #define RANGES_COROUTINES_HEADER <experimental/coroutine>
531 #define RANGES_COROUTINES_NS std::experimental
532 #endif
533 #endif
534 #ifndef RANGES_CXX_COROUTINES
535 #define RANGES_CXX_COROUTINES RANGES_CXX_FEATURE(COROUTINES)
536 #endif
537 #endif
538 
539 // RANGES_CXX14_CONSTEXPR macro (see also BOOST_CXX14_CONSTEXPR)
540 // Note: constexpr implies inline, to retain the same visibility
541 // C++14 constexpr functions are inline in C++11
542 #if RANGES_CXX_CONSTEXPR >= RANGES_CXX_CONSTEXPR_14
543 #define RANGES_CXX14_CONSTEXPR constexpr
544 #else
545 #define RANGES_CXX14_CONSTEXPR inline
546 #endif
547 
548 #ifdef NDEBUG
549 #define RANGES_NDEBUG_CONSTEXPR constexpr
550 #else
551 #define RANGES_NDEBUG_CONSTEXPR inline
552 #endif
553 
554 #ifndef RANGES_CXX_INLINE_VARIABLES
555 #ifdef __cpp_inline_variables
556 #define RANGES_CXX_INLINE_VARIABLES __cpp_inline_variables
557 #elif defined(__clang__) && (__clang_major__ == 3 && __clang_minor__ == 9) && \
558     RANGES_CXX_VER > RANGES_CXX_STD_14
559 // Clang 3.9 supports inline variables in C++17 mode, but doesn't define
560 // __cpp_inline_variables
561 #define RANGES_CXX_INLINE_VARIABLES RANGES_CXX_INLINE_VARIABLES_17
562 #else
563 #define RANGES_CXX_INLINE_VARIABLES RANGES_CXX_FEATURE(INLINE_VARIABLES)
564 #endif // __cpp_inline_variables
565 #endif // RANGES_CXX_INLINE_VARIABLES
566 
567 #if RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17 && \
568     !defined(RANGES_DOXYGEN_INVOKED)
569 #define RANGES_INLINE_VAR
570 #define RANGES_INLINE_VARIABLE(type, name)                           \
571     namespace                                                        \
572     {                                                                \
573         constexpr auto & name = ::ranges::static_const<type>::value; \
574     }
575 #else // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
576 #define RANGES_INLINE_VAR inline
577 #define RANGES_INLINE_VARIABLE(type, name) \
578     inline constexpr type name{};          \
579     /**/
580 #endif // RANGES_CXX_INLINE_VARIABLES
581 
582 #if defined(RANGES_DOXYGEN_INVOKED)
583 #define RANGES_DEFINE_CPO(type, name) \
584     inline constexpr type name{};     \
585     /**/
586 #elif RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17
587 #define RANGES_DEFINE_CPO(type, name)                                \
588     namespace                                                        \
589     {                                                                \
590         constexpr auto & name = ::ranges::static_const<type>::value; \
591     }                                                                \
592     /**/
593 #else // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
594 #define RANGES_DEFINE_CPO(type, name) \
595     namespace _                       \
596     {                                 \
597         inline constexpr type name{}; \
598     }                                 \
599     using namespace _;                \
600     /**/
601 #endif // RANGES_CXX_INLINE_VARIABLES
602 
603 #ifndef RANGES_DOXYGEN_INVOKED
604 #define RANGES_HIDDEN_DETAIL(...) __VA_ARGS__
605 #else
606 #define RANGES_HIDDEN_DETAIL(...)
607 #endif
608 
609 #ifndef RANGES_DOXYGEN_INVOKED
610 #define RANGES_ADL_BARRIER_FOR(S) S##_ns
611 #define RANGES_STRUCT_WITH_ADL_BARRIER(S) \
612     _ranges_adl_barrier_noop_;            \
613     namespace RANGES_ADL_BARRIER_FOR(S)   \
614     {                                     \
615         struct S;                         \
616     }                                     \
617     using RANGES_ADL_BARRIER_FOR(S)::S;   \
618     struct RANGES_ADL_BARRIER_FOR(S)::S /**/
619 #else
620 #define RANGES_ADL_BARRIER_FOR(S)
621 #define RANGES_STRUCT_WITH_ADL_BARRIER(S) S
622 #endif
623 
624 #ifndef RANGES_DOXYGEN_INVOKED
625 #define RANGES_FUNC_BEGIN(NAME) \
626     struct NAME##_fn            \
627     {
628 #define RANGES_FUNC_END(NAME) \
629     }                         \
630     ;                         \
631     RANGES_INLINE_VARIABLE(NAME##_fn, NAME)
632 #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/
633 #define RANGES_FUNC_CONST_(...) (__VA_ARGS__) const
634 #else
635 #define RANGES_FUNC_BEGIN(NAME)
636 #define RANGES_FUNC_END(NAME)
637 #define RANGES_FUNC(NAME) NAME
638 #endif
639 
640 #ifndef RANGES_CXX_DEDUCTION_GUIDES
641 #if defined(__clang__) && defined(__apple_build_version__)
642 // Apple's clang version doesn't do deduction guides very well.
643 #define RANGES_CXX_DEDUCTION_GUIDES 0
644 #elif defined(__cpp_deduction_guides)
645 #define RANGES_CXX_DEDUCTION_GUIDES __cpp_deduction_guides
646 #else
647 #define RANGES_CXX_DEDUCTION_GUIDES RANGES_CXX_FEATURE(DEDUCTION_GUIDES)
648 #endif // __cpp_deduction_guides
649 #endif // RANGES_CXX_DEDUCTION_GUIDES
650 
651 // __VA_OPT__
652 #ifndef RANGES_CXX_VA_OPT
653 #if __cplusplus > 201703L
654 #define RANGES_CXX_THIRD_ARG_(A, B, C, ...) C
655 #define RANGES_CXX_VA_OPT_I_(...) RANGES_CXX_THIRD_ARG_(__VA_OPT__(, ), 1, 0, ?)
656 #define RANGES_CXX_VA_OPT RANGES_CXX_VA_OPT_I_(?)
657 #else
658 #define RANGES_CXX_VA_OPT 0
659 #endif
660 #endif // RANGES_CXX_VA_OPT
661 
662 #ifndef RANGES_CXX_IF_CONSTEXPR
663 #ifdef __cpp_if_constexpr
664 #define RANGES_CXX_IF_CONSTEXPR __cpp_if_constexpr
665 #else
666 #define RANGES_CXX_IF_CONSTEXPR RANGES_CXX_FEATURE(IF_CONSTEXPR)
667 #endif
668 #endif // RANGES_CXX_IF_CONSTEXPR
669 
670 // Its not enough for the compiler to support this; the stdlib must support it too.
671 #ifndef RANGES_CXX_ALIGNED_NEW
672 #if(!defined(_LIBCPP_VERSION) ||                                                 \
673     (_LIBCPP_VERSION >= 4000 && !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION))) && \
674     (!defined(__GLIBCXX__) || (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7))
675 #if defined(__cpp_aligned_new)
676 #define RANGES_CXX_ALIGNED_NEW __cpp_aligned_new
677 #else
678 #define RANGES_CXX_ALIGNED_NEW RANGES_CXX_FEATURE(ALIGNED_NEW)
679 #endif
680 #else // _LIBCPP_VERSION < 4000 || __GLIBCXX__ < 20170502
681 #define RANGES_CXX_ALIGNED_NEW 0L
682 #endif
683 #endif // RANGES_CXX_ALIGNED_NEW
684 
685 #if defined(__clang__)
686 #define RANGES_IS_SAME(...) __is_same(__VA_ARGS__)
687 #elif defined(__GNUC__) && __GNUC__ >= 6
688 #define RANGES_IS_SAME(...) __is_same_as(__VA_ARGS__)
689 #elif RANGES_CXX_TRAIT_VARIABLE_TEMPLATES
690 #define RANGES_IS_SAME(...) std::is_same_v<__VA_ARGS__>
691 #else
692 #define RANGES_IS_SAME(...) std::is_same<__VA_ARGS__>::value
693 #endif
694 
695 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93667
696 #if defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address) && \
697     !(defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 10)
698 #define RANGES_NO_UNIQUE_ADDRESS [[no_unique_address]]
699 #else
700 #define RANGES_NO_UNIQUE_ADDRESS
701 #endif
702 
703 #if defined(__clang__)
704 #if __has_attribute(no_sanitize)
705 #define RANGES_INTENDED_MODULAR_ARITHMETIC \
706     __attribute__((__no_sanitize__("unsigned-integer-overflow")))
707 #else
708 #define RANGES_INTENDED_MODULAR_ARITHMETIC
709 #endif
710 #else
711 #define RANGES_INTENDED_MODULAR_ARITHMETIC
712 #endif
713 
714 #ifndef RANGES_CONSTEXPR_IF
715 #if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
716 #define RANGES_CONSTEXPR_IF(...) false) \
717     {} else if constexpr(__VA_ARGS__
718 #else
719 #define RANGES_CONSTEXPR_IF(...) __VA_ARGS__
720 #endif
721 #endif // RANGES_CONSTEXPR_IF
722 
723 #if !defined(RANGES_BROKEN_CPO_LOOKUP) && !defined(RANGES_DOXYGEN_INVOKED) && \
724     (defined(RANGES_WORKAROUND_GCC_UNFILED0) || defined(RANGES_WORKAROUND_MSVC_895622))
725 #define RANGES_BROKEN_CPO_LOOKUP 1
726 #endif
727 #ifndef RANGES_BROKEN_CPO_LOOKUP
728 #define RANGES_BROKEN_CPO_LOOKUP 0
729 #endif
730 
731 #ifndef RANGES_NODISCARD
732 #if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
733 #if defined(__clang__) && __cplusplus < 201703L
734 // clang complains about using nodiscard in C++14 mode.
735 #define RANGES_NODISCARD                           \
736     RANGES_DIAGNOSTIC_PUSH                         \
737     RANGES_DIAGNOSTIC_IGNORE("-Wc++1z-extensions") \
738     [[nodiscard]] RANGES_DIAGNOSTIC_POP /**/
739 #else
740 #define RANGES_NODISCARD [[nodiscard]]
741 #endif
742 #else
743 #define RANGES_NODISCARD
744 #endif
745 #endif
746 
747 #ifndef RANGES_EMPTY_BASES
748 #ifdef _MSC_VER
749 #define RANGES_EMPTY_BASES __declspec(empty_bases)
750 #else
751 #define RANGES_EMPTY_BASES
752 #endif
753 #endif
754 
755 #endif
756