// // Copyright (c) 2016-2018 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].SML requires C++14 support (Clang-3.4+, GCC-5.1+, MSVC-2015+)" #else #define BOOST_SML_VERSION 1'1'0 #define BOOST_SML_NAMESPACE_BEGIN \ namespace boost { \ namespace sml { \ inline namespace v1_1_0 { #define BOOST_SML_NAMESPACE_END \ } \ } \ } #if defined(__clang__) #define __BOOST_SML_UNUSED __attribute__((unused)) #define __BOOST_SML_VT_INIT \ {} #define __BOOST_SML_ZERO_SIZE_ARRAY(...) __VA_ARGS__ _[0] #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 __has_builtin(...) 0 #endif #define __BOOST_SML_UNUSED __attribute__((unused)) #define __BOOST_SML_VT_INIT \ {} #define __BOOST_SML_ZERO_SIZE_ARRAY(...) __VA_ARGS__ _[0] #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" #elif defined(_MSC_VER) #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 (_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) #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 {}; 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 {}; template struct conditional { using type = T; }; template struct conditional { using type = F; }; 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) 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) 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 __cplusplus > 201402L && __cpp_noexcept_function_type >= 201510 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; } namespace aux { using swallow = int[]; 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, type_list> : type_list {}; template struct join, type_list, Ts...> : join, Ts...> {}; 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, Us...> : join, Us...> {}; template using join_t = typename join::type; template struct unique_impl; template struct unique_impl, T2, Ts...> : conditional_t, T1>::value, unique_impl, Rs...>, Ts...>, unique_impl>, Rs..., T2>, Ts...>> {}; template struct unique_impl> : type_list {}; 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 : conditional_t, T1>::value, false_type, is_unique>, Ts...>> {}; template using is_unique_t = is_unique; template