File indexing completed on 2025-01-18 09:37:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_EXPERIMENTAL_TYPES_HPP
0011 #define BOOST_HANA_EXPERIMENTAL_TYPES_HPP
0012
0013 #include <boost/hana/bool.hpp>
0014 #include <boost/hana/concept/metafunction.hpp>
0015 #include <boost/hana/config.hpp>
0016 #include <boost/hana/detail/any_of.hpp>
0017 #include <boost/hana/detail/type_at.hpp>
0018 #include <boost/hana/fwd/at.hpp>
0019 #include <boost/hana/fwd/contains.hpp>
0020 #include <boost/hana/fwd/core/tag_of.hpp>
0021 #include <boost/hana/fwd/equal.hpp>
0022 #include <boost/hana/fwd/is_empty.hpp>
0023 #include <boost/hana/fwd/transform.hpp>
0024 #include <boost/hana/fwd/unpack.hpp>
0025 #include <boost/hana/type.hpp>
0026
0027 #include <cstddef>
0028 #include <type_traits>
0029 #include <utility>
0030
0031
0032 namespace boost { namespace hana {
0033 namespace experimental {
0034
0035
0036
0037
0038
0039
0040
0041
0042 template <typename ...T>
0043 struct types;
0044
0045 struct types_tag;
0046
0047 template <typename ...T>
0048 struct types { };
0049 }
0050
0051 template <typename ...T>
0052 struct tag_of<experimental::types<T...>> {
0053 using type = experimental::types_tag;
0054 };
0055
0056
0057 template <>
0058 struct unpack_impl<hana::experimental::types_tag> {
0059 template <typename ...T, typename F, typename = typename std::enable_if<
0060 !hana::Metafunction<F>::value
0061 >::type>
0062 static constexpr decltype(auto) apply(hana::experimental::types<T...> const&, F&& f) {
0063 return static_cast<F&&>(f)(hana::type<T>{}...);
0064 }
0065
0066 template <typename ...T, typename F, typename = typename std::enable_if<
0067 hana::Metafunction<F>::value
0068 >::type>
0069 static constexpr hana::type<typename F::template apply<T...>::type>
0070 apply(hana::experimental::types<T...> const&, F const&) { return {}; }
0071 };
0072
0073
0074 template <>
0075 struct transform_impl<hana::experimental::types_tag> {
0076 template <typename ...T, typename F, typename = typename std::enable_if<
0077 !hana::Metafunction<F>::value
0078 >::type>
0079 static constexpr auto apply(hana::experimental::types<T...> const&, F&& f)
0080 -> hana::experimental::types<typename decltype(+f(hana::type<T>{}))::type...>
0081 { return {}; }
0082
0083 template <typename ...T, typename F, typename = typename std::enable_if<
0084 hana::Metafunction<F>::value
0085 >::type>
0086 static constexpr hana::experimental::types<typename F::template apply<T>::type...>
0087 apply(hana::experimental::types<T...> const&, F const&) { return {}; }
0088 };
0089
0090
0091 template <>
0092 struct at_impl<hana::experimental::types_tag> {
0093 template <typename ...T, typename N>
0094 static constexpr auto
0095 apply(hana::experimental::types<T...> const&, N const&) {
0096 using Nth = typename detail::type_at<N::value, T...>::type;
0097 return hana::type<Nth>{};
0098 }
0099 };
0100
0101 template <>
0102 struct is_empty_impl<hana::experimental::types_tag> {
0103 template <typename ...T>
0104 static constexpr hana::bool_<sizeof...(T) == 0>
0105 apply(hana::experimental::types<T...> const&)
0106 { return {}; }
0107 };
0108
0109 template <>
0110 struct drop_front_impl<hana::experimental::types_tag> {
0111 template <std::size_t n, typename ...T, std::size_t ...i>
0112 static hana::experimental::types<typename detail::type_at<i + n, T...>::type...>
0113 helper(std::index_sequence<i...>);
0114
0115 template <typename ...T, typename N>
0116 static constexpr auto
0117 apply(hana::experimental::types<T...> const&, N const&) {
0118 constexpr std::size_t n = N::value > sizeof...(T) ? sizeof...(T) : N::value;
0119 using Indices = std::make_index_sequence<sizeof...(T) - n>;
0120 return decltype(helper<n, T...>(Indices{})){};
0121 }
0122 };
0123
0124
0125 template <>
0126 struct contains_impl<hana::experimental::types_tag> {
0127 template <typename U>
0128 struct is_same_as {
0129 template <typename T>
0130 struct apply {
0131 static constexpr bool value = std::is_same<U, T>::value;
0132 };
0133 };
0134
0135 template <typename ...T, typename U>
0136 static constexpr auto apply(hana::experimental::types<T...> const&, U const&)
0137 -> hana::bool_<
0138 detail::any_of<is_same_as<typename U::type>::template apply, T...>::value
0139 >
0140 { return {}; }
0141
0142 static constexpr hana::false_ apply(...) { return {}; }
0143 };
0144
0145
0146 template <>
0147 struct equal_impl<hana::experimental::types_tag, hana::experimental::types_tag> {
0148 template <typename Types>
0149 static constexpr hana::true_ apply(Types const&, Types const&)
0150 { return {}; }
0151
0152 template <typename Ts, typename Us>
0153 static constexpr hana::false_ apply(Ts const&, Us const&)
0154 { return {}; }
0155 };
0156 }}
0157
0158 #endif