You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

719 lines
28KB

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