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