// // Copyright (c) 2016-2024 Kris Jusiak (kris at jusiak dot net) // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_SML_HPP #define BOOST_SML_HPP #if (__cplusplus < 201305L && _MSC_VER < 1900) #error "[Boost::ext].SML requires C++14 support (Clang-3.4+, GCC-5.1+, MSVC-2015+)" #else #if defined(__ICCARM__) && __IAR_SYSTEMS_ICC__ < 8 #error "[Boost::ext].SML requires C++14 support (IAR C/C++ ARM 8.1+)" #endif #define BOOST_SML_VERSION 1'1'13 #define BOOST_SML_NAMESPACE_BEGIN \ namespace boost { \ inline namespace ext { \ namespace sml { \ inline namespace v1_1_13 { #define BOOST_SML_NAMESPACE_END \ } \ } \ } \ } #if defined(__clang__) #define __BOOST_SML_UNUSED __attribute__((unused)) #define __BOOST_SML_VT_INIT \ {} #if !defined(BOOST_SML_CFG_DISABLE_MIN_SIZE) #define __BOOST_SML_ZERO_SIZE_ARRAY(...) __VA_ARGS__ _[0] #else #define __BOOST_SML_ZERO_SIZE_ARRAY(...) #endif #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) #define __BOOST_SML_TEMPLATE_KEYWORD template #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" #pragma clang diagnostic ignored "-Wzero-length-array" #elif defined(__GNUC__) #if !defined(__has_builtin) #define __BOOST_SML_DEFINED_HAS_BUILTIN #define __has_builtin(...) 0 #endif #define __BOOST_SML_UNUSED __attribute__((unused)) #define __BOOST_SML_VT_INIT \ {} #if !defined(BOOST_SML_CFG_DISABLE_MIN_SIZE) #define __BOOST_SML_ZERO_SIZE_ARRAY(...) __VA_ARGS__ _[0]{} #else #define __BOOST_SML_ZERO_SIZE_ARRAY(...) #endif #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) __VA_ARGS__ ? __VA_ARGS__ : 1 #define __BOOST_SML_TEMPLATE_KEYWORD template #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #if defined(__GNUC__) && (__GNUC__ >= 10) #pragma GCC diagnostic ignored "-Wsubobject-linkage" #endif #elif defined(_MSC_VER) && !defined(__clang__) #define __BOOST_SML_DEFINED_HAS_BUILTIN #define __has_builtin(...) __has_builtin##__VA_ARGS__ #define __has_builtin__make_integer_seq(...) 1 #define __BOOST_SML_UNUSED #define __BOOST_SML_VT_INIT #define __BOOST_SML_ZERO_SIZE_ARRAY(...) #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) __VA_ARGS__ ? __VA_ARGS__ : 1 #if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1910 // MSVC 2017 #define __BOOST_SML_TEMPLATE_KEYWORD template #else #define __BOOST_SML_TEMPLATE_KEYWORD #endif #pragma warning(disable : 4503) #pragma warning(disable : 4200) #elif defined(__ICCARM__) #if !defined(__has_builtin) #define __BOOST_SML_DEFINED_HAS_BUILTIN #define __has_builtin(...) 0 #endif /* Needs IAR language extensions */ #define __BOOST_SML_UNUSED __attribute__((unused)) #define __BOOST_SML_VT_INIT \ {} #define __BOOST_SML_ZERO_SIZE_ARRAY(...) #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) __VA_ARGS__ ? __VA_ARGS__ : 1 #define __BOOST_SML_TEMPLATE_KEYWORD template #endif BOOST_SML_NAMESPACE_BEGIN #define __BOOST_SML_REQUIRES(...) typename aux::enable_if<__VA_ARGS__, int>::type = 0 namespace aux { using byte = unsigned char; struct none_type {}; template struct type_wrapper {}; template struct non_type {}; template struct pair {}; template struct type_list { using type = type_list; }; template struct bool_list { using type = bool_list; }; template struct inherit : Ts... { using type = inherit; }; template struct identity { using type = T; }; template T &&declval(); template struct integral_constant { using type = integral_constant; static constexpr T value = V; }; using true_type = integral_constant; using false_type = integral_constant; template using void_t = void; template struct always : true_type {}; template struct never : false_type {}; namespace detail { template struct conditional; template <> struct conditional { template using fn = T; }; template <> struct conditional { template using fn = T; }; } // namespace detail template struct conditional { using type = typename detail::conditional::template fn; }; template using conditional_t = typename conditional::type; template struct enable_if {}; template struct enable_if { using type = T; }; template using enable_if_t = typename enable_if::type; template struct is_same : false_type {}; template struct is_same : true_type {}; template #if defined(_MSC_VER) && !defined(__clang__) struct is_base_of : integral_constant { }; #else using is_base_of = integral_constant; #endif template decltype(T(declval()...), true_type{}) test_is_constructible(int); template false_type test_is_constructible(...); template #if defined(_MSC_VER) && !defined(__clang__) struct is_constructible : decltype(test_is_constructible(0)) { }; #else using is_constructible = decltype(test_is_constructible(0)); #endif template struct is_empty_base : T { U _; }; template struct is_empty : aux::integral_constant) == sizeof(none_type)> {}; template struct function_traits; template struct function_traits { using args = type_list; }; template struct function_traits { using args = type_list; }; template struct function_traits { using args = type_list; }; template struct function_traits { using args = type_list; }; #if defined(__cpp_noexcept_function_type) template struct function_traits { using args = type_list; }; template struct function_traits { using args = type_list; }; template struct function_traits { using args = type_list; }; template struct function_traits { using args = type_list; }; #endif template using function_traits_t = typename function_traits::args; template struct remove_const { using type = T; }; template struct remove_const { using type = T; }; template using remove_const_t = typename remove_const::type; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template using remove_reference_t = typename remove_reference::type; template struct remove_pointer { using type = T; }; template struct remove_pointer { using type = T; }; template using remove_pointer_t = typename remove_pointer::type; } // namespace aux namespace aux { using swallow = int[]; template class L, class... Ts> void for_each(L, F f) { #if defined(__cpp_fold_expressions) (f(identity{}),...); #else (void)aux::swallow{0, (f(identity{}), 0)...}; #endif } template struct index_sequence { using type = index_sequence; }; #if __has_builtin(__make_integer_seq) template struct integer_sequence; template struct integer_sequence { using type = index_sequence; }; template struct make_index_sequence_impl { using type = typename __make_integer_seq::type; }; #else template struct concat; template struct concat, index_sequence> : index_sequence {}; template struct make_index_sequence_impl : concat::type, typename make_index_sequence_impl::type>::type {}; template <> struct make_index_sequence_impl<0> : index_sequence<> {}; template <> struct make_index_sequence_impl<1> : index_sequence<0> {}; #endif template using make_index_sequence = typename make_index_sequence_impl::type; template struct join { using type = type_list<>; }; template struct join { using type = T; }; template struct join> : type_list {}; template struct join, type_list> : type_list {}; template struct join, type_list, Us...> : join, Us...> {}; template struct join, type_list, type_list, type_list, Us...> : join, Us...> {}; template struct join, type_list, type_list, type_list, type_list, type_list, type_list, type_list, Us...> : join, Us...> {}; template struct join, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, Us...> : join, Us...> {}; template struct join, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, Us...> : join, Us...> {}; template struct join, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, Us...> : join, Us...> {}; template using join_t = typename join::type; template struct add_unique { using type = conditional_t, Accumulator>::value, Accumulator, inherit>>; }; template using add_unique_t = typename add_unique::type; template > struct extract_types_impl; template struct extract_types_impl, type_wrapper> { using type = type_wrapper; }; template struct extract_types_impl...>, type_wrapper> { using type = type_wrapper; }; template struct extract_types_impl, type_wrapper>, type_wrapper> : extract_types_impl, type_wrapper> {}; template using extract_types = typename extract_types_impl::type; template struct unique_impl; template struct unique_impl> : type_list {}; template struct unique_impl, Head, Tail...> { private: using current_set = inherit...>; using next_uniques = conditional_t< is_base_of, current_set>::value, type_wrapper, type_wrapper >; public: using type = typename unique_impl::type; }; template struct unique_impl, T1, T2, T3, T4, T5, T6, T7, T8, Tail...> { private: using initial_set = inherit...>; using after_1 = add_unique_t; using after_2 = add_unique_t; using after_3 = add_unique_t; using after_4 = add_unique_t; using after_5 = add_unique_t; using after_6 = add_unique_t; using after_7 = add_unique_t; using after_8 = add_unique_t; using batch_result = extract_types; public: using type = typename unique_impl::type; }; template struct unique_impl, T01, T02, T03, T04, T05, T06, T07, T08, T09, T10, T11, T12, T13, T14, T15, T16, Tail...> { private: using initial_set = inherit...>; using after_01 = add_unique_t; using after_02 = add_unique_t; using after_03 = add_unique_t; using after_04 = add_unique_t; using after_05 = add_unique_t; using after_06 = add_unique_t; using after_07 = add_unique_t; using after_08 = add_unique_t; using after_09 = add_unique_t; using after_10 = add_unique_t; using after_11 = add_unique_t; using after_12 = add_unique_t; using after_13 = add_unique_t; using after_14 = add_unique_t; using after_15 = add_unique_t; using after_16 = add_unique_t; using batch_result = extract_types; public: using type = typename unique_impl::type; }; template struct unique_impl, T01, T02, T03, T04, T05, T06, T07, T08, T09, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, Tail...> { private: using initial_set = inherit...>; using after_01 = add_unique_t; using after_02 = add_unique_t; using after_03 = add_unique_t; using after_04 = add_unique_t; using after_05 = add_unique_t; using after_06 = add_unique_t; using after_07 = add_unique_t; using after_08 = add_unique_t; using after_09 = add_unique_t; using after_10 = add_unique_t; using after_11 = add_unique_t; using after_12 = add_unique_t; using after_13 = add_unique_t; using after_14 = add_unique_t; using after_15 = add_unique_t; using after_16 = add_unique_t; using after_17 = add_unique_t; using after_18 = add_unique_t; using after_19 = add_unique_t; using after_20 = add_unique_t; using after_21 = add_unique_t; using after_22 = add_unique_t; using after_23 = add_unique_t; using after_24 = add_unique_t; using after_25 = add_unique_t; using after_26 = add_unique_t; using after_27 = add_unique_t; using after_28 = add_unique_t; using after_29 = add_unique_t; using after_30 = add_unique_t; using after_31 = add_unique_t; using after_32 = add_unique_t; using batch_result = extract_types; public: using type = typename unique_impl::type; }; template struct unique_impl, T01, T02, T03, T04, T05, T06, T07, T08, T09, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50, T51, T52, T53, T54, T55, T56, T57, T58, T59, T60, T61, T62, T63, T64, Tail...> { private: using initial_set = inherit...>; using after_01 = add_unique_t; using after_02 = add_unique_t; using after_03 = add_unique_t; using after_04 = add_unique_t; using after_05 = add_unique_t; using after_06 = add_unique_t; using after_07 = add_unique_t; using after_08 = add_unique_t; using after_09 = add_unique_t; using after_10 = add_unique_t; using after_11 = add_unique_t; using after_12 = add_unique_t; using after_13 = add_unique_t; using after_14 = add_unique_t; using after_15 = add_unique_t; using after_16 = add_unique_t; using after_17 = add_unique_t; using after_18 = add_unique_t; using after_19 = add_unique_t; using after_20 = add_unique_t; using after_21 = add_unique_t; using after_22 = add_unique_t; using after_23 = add_unique_t; using after_24 = add_unique_t; using after_25 = add_unique_t; using after_26 = add_unique_t; using after_27 = add_unique_t; using after_28 = add_unique_t; using after_29 = add_unique_t; using after_30 = add_unique_t; using after_31 = add_unique_t; using after_32 = add_unique_t; using after_33 = add_unique_t; using after_34 = add_unique_t; using after_35 = add_unique_t; using after_36 = add_unique_t; using after_37 = add_unique_t; using after_38 = add_unique_t; using after_39 = add_unique_t; using after_40 = add_unique_t; using after_41 = add_unique_t; using after_42 = add_unique_t; using after_43 = add_unique_t; using after_44 = add_unique_t; using after_45 = add_unique_t; using after_46 = add_unique_t; using after_47 = add_unique_t; using after_48 = add_unique_t; using after_49 = add_unique_t; using after_50 = add_unique_t; using after_51 = add_unique_t; using after_52 = add_unique_t; using after_53 = add_unique_t; using after_54 = add_unique_t; using after_55 = add_unique_t; using after_56 = add_unique_t; using after_57 = add_unique_t; using after_58 = add_unique_t; using after_59 = add_unique_t; using after_60 = add_unique_t; using after_61 = add_unique_t; using after_62 = add_unique_t; using after_63 = add_unique_t; using after_64 = add_unique_t; using batch_result = extract_types; public: using type = typename unique_impl::type; }; template struct unique : unique_impl, Ts...> {}; template struct unique : type_list {}; template using unique_t = typename unique::type; template struct is_unique; template struct is_unique : true_type {}; template struct is_unique, T, Ts...> : conditional_t, inherit...>>::value, false_type, is_unique, Ts...>> {}; template using is_unique_t = is_unique, Ts...>; template