// Copyright 2022 - 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_DECIMAL_DETAIL_CONCEPTS #define BOOST_DECIMAL_DETAIL_CONCEPTS #include #include #ifndef BOOST_DECIMAL_BUILD_MODULE #include #endif // GCC-11 yields internal compiler errors when using the concepts /* ./boost/decimal/detail/concepts.hpp:239:80: note: in definition of macro 'BOOST_DECIMAL_REQUIRES_RETURN' 239 | #define BOOST_DECIMAL_REQUIRES_RETURN(X, T, ReturnType) -> ReturnType requires X | ^ 0xe3223b internal_error(char const*, ...) ???:0 0xf56ed4 duplicate_decls(tree_node*, tree_node*, bool, bool) ???:0 0xf60a2b pushdecl_namespace_level(tree_node*, bool) ???:0 0x10801ca push_template_decl(tree_node*, bool) ???:0 0x1527ec1 do_friend(tree_node*, tree_node*, tree_node*, tree_node*, overload_flags, bool) ???:0 0xfc4e1e grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*, decl_context, int, tree_node**) ???:0 0x100dcf4 grokfield(cp_declarator const*, cp_decl_specifier_seq*, tree_node*, bool, tree_node*, tree_node*) ???:0 0x149dce3 c_parse_file() ???:0 0x148d4de c_common_parse_file() ???:0 */ #if (__cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) && !defined(BOOST_MATH_DISABLE_CONCEPTS) &&\ (!defined(__GNUC__) || __GNUC__ != 11) #if __has_include() #ifndef BOOST_DECIMAL_BUILD_MODULE #include #include #include #include #include #include #include #endif namespace boost::decimal::detail::concepts { template struct op_valid_impl { template static constexpr auto test(int) -> decltype(std::declval()(std::declval(), std::declval()), void(), std::true_type()); template static constexpr auto test(...) -> std::false_type; using type = decltype(test(0)); }; template using op_valid_t = typename op_valid_impl::type; template inline constexpr bool op_valid_v = op_valid_t::value; // Detector for class member functions struct nonesuch { nonesuch(const nonesuch&) = delete; ~nonesuch() = delete; void operator=(const nonesuch&) = delete; }; template typename Op, typename... Args> struct detector { using value_t = std::false_type; using type = Default; }; template typename Op, typename... Args> struct detector>, Op, Args...> { using value_t = std::true_type; using type = Op; }; template typename Op, typename... Args> using is_detected = typename detector::value_t; template typename Op, typename... Args> using detected_t = typename detector::type; #define BOOST_DECIMAL_HAS_MEMBER_FUNCTION(member) \ template \ using has_##member##_t = decltype(std::declval().member()); \ \ template \ inline constexpr bool has_##member##_v = is_detected::value; BOOST_DECIMAL_HAS_MEMBER_FUNCTION(begin) BOOST_DECIMAL_HAS_MEMBER_FUNCTION(end) BOOST_DECIMAL_HAS_MEMBER_FUNCTION(real) BOOST_DECIMAL_HAS_MEMBER_FUNCTION(imag) template concept integral = boost::decimal::detail::is_integral_v; template concept signed_integral = integral && boost::decimal::detail::is_signed_v; template concept unsigned_integral = integral && boost::decimal::detail::is_unsigned_v; template concept real = boost::decimal::detail::is_floating_point_v; template concept complex = std::is_same_v> || std::is_same_v> #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS || std::is_same_v> #endif ; template concept real_or_complex = real || complex; template concept arithmetic = std::is_arithmetic_v; template concept numerical = arithmetic || real_or_complex; template concept signed_arithmetic = arithmetic && std::is_signed_v; template concept unsigned_arithmetic = arithmetic && std::is_unsigned_v; template concept arbitrary_unsigned_arithmetic_type = unsigned_arithmetic || (op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v> && op_valid_v>); template concept arbitrary_signed_arithmetic_type = signed_arithmetic || (arbitrary_unsigned_arithmetic_type && (op_valid_v> || std::numeric_limits::is_signed)); template concept arbitrary_arithmetic_type = arbitrary_unsigned_arithmetic_type || arbitrary_signed_arithmetic_type; template concept arbitrary_unsigned_integer_type = arbitrary_unsigned_arithmetic_type && std::numeric_limits::is_integer; template concept arbitrary_signed_integer_type = arbitrary_signed_arithmetic_type && std::numeric_limits::is_integer; template concept arbitrary_integer_type = arbitrary_unsigned_integer_type || arbitrary_signed_integer_type; template concept arbitrary_real_type = arbitrary_arithmetic_type && !std::numeric_limits::is_integer; template concept arbitrary_complex_type = complex || (has_real_v && has_imag_v); template concept arbitrary_real_or_complex_type = arbitrary_real_type || arbitrary_complex_type; template concept arbitrary_numerical_type = arbitrary_real_or_complex_type || arbitrary_arithmetic_type; template concept derived_from = std::is_base_of_v && std::is_convertible_v; template concept forward_iterator = derived_from::iterator_category, std::forward_iterator_tag>; template concept bidirectional_iterator = derived_from::iterator_category, std::bidirectional_iterator_tag>; template concept random_access_iterator = derived_from::iterator_category, std::random_access_iterator_tag>; template concept output_iterator = derived_from::iterator_category, std::input_iterator_tag> && derived_from::iterator_category, std::output_iterator_tag>; template concept is_container = has_begin_v && has_end_v; template concept random_access_container = is_container && boost::decimal::detail::concepts::random_access_iterator; template concept decimal_floating_point_type = boost::decimal::detail::is_decimal_floating_point_v; template concept fast_decimal_floating_point_type = boost::decimal::detail::is_fast_type_v; } // boost::decimal::detail::concepts #define BOOST_DECIMAL_HAS_CONCEPTS 1 #define BOOST_DECIMAL_INTEGRAL boost::decimal::detail::concepts::integral #define BOOST_DECIMAL_SIGNED_INTEGRAL boost::decimal::detail::concepts::signed_integral #define BOOST_DECIMAL_UNSIGNED_INTEGRAL boost::decimal::detail::concepts::unsigned_integral #define BOOST_DECIMAL_REAL boost::decimal::detail::concepts::real #define BOOST_DECIMAL_COMPLEX boost::decimal::detail::concepts::complex #define BOOST_DECIMAL_REAL_OR_COMPLEX boost::decimal::detail::concepts::real_or_complex #define BOOST_DECIMAL_ARITHMETIC boost::decimal::detail::concepts::arithmetic #define BOOST_DECIMAL_NUMERICAL boost::decimal::detail::concepts::numerical #define BOOST_DECIMAL_SIGNED_ARITHMETIC boost::decimal::detail::concepts::signed_arithmetic #define BOOST_DECIMAL_UNSIGNED_ARITHMETIC boost::decimal::detail::concepts::unsigned_arithmetic #define BOOST_DECIMAL_ARBITRARY_UNSIGNED_ARITHMETIC boost::decimal::detail::concepts::arbitrary_unsigned_arithmetic_type #define BOOST_DECIMAL_ARBITRARY_SIGNED_ARITHMETIC boost::decimal::detail::concepts::arbitrary_signed_arithmetic_type #define BOOST_DECIMAL_ARBITRARY_ARITHMETIC boost::decimal::detail::concepts::arbitrary_arithmetic_type #define BOOST_DECIMAL_ARBITRARY_UNSIGNED_INTEGER boost::decimal::detail::concepts::arbitrary_unsigned_integer_type #define BOOST_DECIMAL_ARBITRARY_SIGNED_INTEGER boost::decimal::detail::concepts::arbitrary_signed_integer_type #define BOOST_DECIMAL_ARBITRARY_INTEGER boost::decimal::detail::concepts::arbitrary_integer_type #define BOOST_DECIMAL_ARBITRARY_REAL boost::decimal::detail::concepts::arbitrary_real_type #define BOOST_DECIMAL_ARBITRARY_COMPLEX boost::decimal::detail::concepts::arbitrary_complex_type #define BOOST_DECIMAL_ARBITRARY_REAL_OR_COMPLEX boost::decimal::detail::concepts::arbitrary_real_or_complex_type #define BOOST_DECIMAL_ARBITRARY_NUMERICAL boost::decimal::detail::concepts::arbitrary_numerical_type #define BOOST_DECIMAL_DECIMAL_FLOATING_TYPE boost::decimal::detail::concepts::decimal_floating_point_type #define BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE boost::decimal::detail::concepts::fast_decimal_floating_point_type #define BOOST_DECIMAL_CONTAINER boost::decimal::detail::concepts::is_container #define BOOST_DECIMAL_RANDOM_ACCESS_CONTAINER boost::decimal::detail::concepts::random_access_container #define BOOST_DECIMAL_FORWARD_ITER boost::decimal::detail::concepts::forward_iterator #define BOOST_DECIMAL_BIDIRECTIONAL_ITER boost::decimal::detail::concepts::bidirectional_iterator #define BOOST_DECIMAL_RANDOM_ACCESS_ITER boost::decimal::detail::concepts::random_access_iterator #define BOOST_DECIMAL_OUTPUT_ITER(I, T) boost::decimal::detail::concepts::output_iterator #define BOOST_DECIMAL_REQUIRES_ITER(X) requires X #define BOOST_DECIMAL_REQUIRES(X, T) -> T requires (X) #define BOOST_DECIMAL_REQUIRES_TWO(X1, T1, X2, T2) -> detail::promote_args_t requires (X1 && X2) #define BOOST_DECIMAL_REQUIRES_TWO_RETURN(X1, T1, X2, T2, ReturnType) -> ReturnType requires (X1 && X2) #define BOOST_DECIMAL_REQUIRES_THREE(X1, T1, X2, T2, X3, T3) -> detail::promote_args_t requires (X1 && X2 && X3) #define BOOST_DECIMAL_REQUIRES_RETURN(X, T, ReturnType) -> ReturnType requires (X) #ifdef BOOST_DECIMAL_EXEC_COMPATIBLE #include namespace boost::decimal::detail::concepts { template concept execution_policy = std::is_execution_policy_v>; } // Namespace boost::decimal::detail::concepts #define BOOST_DECIMAL_EXECUTION_POLICY boost::decimal::detail::concepts::execution_policy #endif // Has #endif // Has #endif // C++20 // If concepts are unavailable replace them with typename for compatibility #ifndef BOOST_DECIMAL_INTEGRAL # define BOOST_DECIMAL_INTEGRAL typename #endif #ifndef BOOST_DECIMAL_SIGNED_INTEGRAL # define BOOST_DECIMAL_SIGNED_INTEGRAL typename #endif #ifndef BOOST_DECIMAL_UNSIGNED_INTEGRAL # define BOOST_DECIMAL_UNSIGNED_INTEGRAL typename #endif #ifndef BOOST_DECIMAL_REAL # define BOOST_DECIMAL_REAL typename #endif #ifndef BOOST_DECIMAL_COMPLEX # define BOOST_DECIMAL_COMPLEX typename #endif #ifndef BOOST_DECIMAL_REAL_OR_COMPLEX # define BOOST_DECIMAL_REAL_OR_COMPLEX typename #endif #ifndef BOOST_DECIMAL_ARITHMETIC # define BOOST_DECIMAL_ARITHMETIC typename #endif #ifndef BOOST_DECIMAL_NUMERICAL # define BOOST_DECIMAL_NUMERICAL typename #endif #ifndef BOOST_DECIMAL_SIGNED_ARITHMETIC # define BOOST_DECIMAL_SIGNED_ARITHMETIC typename #endif #ifndef BOOST_DECIMAL_UNSIGNED_ARITHMETIC # define BOOST_DECIMAL_UNSIGNED_ARITHMETIC typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_UNSIGNED_ARITHMETIC # define BOOST_DECIMAL_ARBITRARY_UNSIGNED_ARITHMETIC typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_SIGNED_ARITHMETIC # define BOOST_DECIMAL_ARBITRARY_SIGNED_ARITHMETIC typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_ARITHMETIC # define BOOST_DECIMAL_ARBITRARY_ARITHMETIC typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_UNSIGNED_INTEGER # define BOOST_DECIMAL_ARBITRARY_UNSIGNED_INTEGER typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_SIGNED_INTEGER # define BOOST_DECIMAL_ARBITRARY_SIGNED_INTEGER typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_INTEGER # define BOOST_DECIMAL_ARBITRARY_INTEGER typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_REAL # define BOOST_DECIMAL_ARBITRARY_REAL typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_COMPLEX # define BOOST_DECIMAL_ARBITRARY_COMPLEX typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_REAL_OR_COMPLEX # define BOOST_DECIMAL_ARBITRARY_REAL_OR_COMPLEX typename #endif #ifndef BOOST_DECIMAL_ARBITRARY_NUMERICAL # define BOOST_DECIMAL_ARBITRARY_NUMERICAL typename #endif #ifndef BOOST_DECIMAL_POLICY # define BOOST_DECIMAL_POLICY typename #endif #ifndef BOOST_DECIMAL_FORWARD_ITER # define BOOST_DECIMAL_FORWARD_ITER typename #endif #ifndef BOOST_DECIMAL_BIDIRECTIONAL_ITER # define BOOST_DECIMAL_BIDIRECTIONAL_ITER typename #endif #ifndef BOOST_DECIMAL_RANDOM_ACCESS_ITER # define BOOST_DECIMAL_RANDOM_ACCESS_ITER typename #endif #ifndef BOOST_DECIMAL_DECIMAL_FLOATING_TYPE # define BOOST_DECIMAL_DECIMAL_FLOATING_TYPE typename #endif #ifndef BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE # define BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE typename #endif #ifndef BOOST_DECIMAL_OUTPUT_ITER # define BOOST_DECIMAL_OUTPUT_ITER(I, T) #endif #ifndef BOOST_DECIMAL_REQUIRES_ITER # define BOOST_DECIMAL_REQUIRES_ITER(X) #endif #ifndef BOOST_DECIMAL_CONTAINER # define BOOST_DECIMAL_CONTAINER typename #endif #ifndef BOOST_DECIMAL_RANDOM_ACCESS_CONTAINER # define BOOST_DECIMAL_RANDOM_ACCESS_CONTAINER typename #endif #ifndef BOOST_DECIMAL_EXECUTION_POLICY # define BOOST_DECIMAL_EXECUTION_POLICY typename #endif #ifndef BOOST_DECIMAL_REQUIRES # define BOOST_DECIMAL_REQUIRES(X, T) -> std::enable_if_t, T> #endif #ifndef BOOST_DECIMAL_REQUIRES_TWO # define BOOST_DECIMAL_REQUIRES_TWO(X1, T1, X2, T2) -> std::enable_if_t && X2, detail::promote_args_t> #endif #ifndef BOOST_DECIMAL_REQUIRES_TWO_RETURN # define BOOST_DECIMAL_REQUIRES_TWO_RETURN(X1, T1, X2, T2, ReturnType) -> std::enable_if_t && X2, ReturnType> #endif #ifndef BOOST_DECIMAL_REQUIRES_THREE # define BOOST_DECIMAL_REQUIRES_THREE(X1, T1, X2, T2, X3, T3) -> std::enable_if_t && X2 && X3, detail::promote_args_t> #endif #ifndef BOOST_DECIMAL_REQUIRES_RETURN # define BOOST_DECIMAL_REQUIRES_RETURN(X, T, ReturnType) -> std::enable_if_t, ReturnType> #endif #endif //BOOST_DECIMAL_DETAIL_CONCEPTS