File indexing completed on 2024-11-15 09:13:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_BASIC_TUPLE_HPP
0011 #define BOOST_HANA_BASIC_TUPLE_HPP
0012
0013 #include <boost/hana/fwd/basic_tuple.hpp>
0014
0015 #include <boost/hana/config.hpp>
0016 #include <boost/hana/detail/decay.hpp>
0017 #include <boost/hana/detail/ebo.hpp>
0018 #include <boost/hana/fwd/at.hpp>
0019 #include <boost/hana/fwd/bool.hpp>
0020 #include <boost/hana/fwd/concept/sequence.hpp>
0021 #include <boost/hana/fwd/core/make.hpp>
0022 #include <boost/hana/fwd/core/tag_of.hpp>
0023 #include <boost/hana/fwd/drop_front.hpp>
0024 #include <boost/hana/fwd/integral_constant.hpp>
0025 #include <boost/hana/fwd/is_empty.hpp>
0026 #include <boost/hana/fwd/length.hpp>
0027 #include <boost/hana/fwd/transform.hpp>
0028 #include <boost/hana/fwd/unpack.hpp>
0029
0030 #include <cstddef>
0031 #include <type_traits>
0032 #include <utility>
0033
0034
0035 namespace boost { namespace hana {
0036 namespace detail {
0037
0038
0039
0040 template <std::size_t> struct bti;
0041
0042 struct from_other { };
0043
0044 template <typename Indices, typename ...Xn>
0045 #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
0046 struct __declspec(empty_bases) basic_tuple_impl;
0047 #else
0048 struct basic_tuple_impl;
0049 #endif
0050
0051 template <std::size_t ...n, typename ...Xn>
0052 #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
0053 struct __declspec(empty_bases) basic_tuple_impl<std::index_sequence<n...>, Xn...>
0054 #else
0055 struct basic_tuple_impl<std::index_sequence<n...>, Xn...>
0056 #endif
0057 : detail::ebo<bti<n>, Xn>...
0058 {
0059 static constexpr std::size_t size_ = sizeof...(Xn);
0060
0061 constexpr basic_tuple_impl() = default;
0062
0063 template <typename Other>
0064 explicit constexpr basic_tuple_impl(detail::from_other, Other&& other)
0065 : detail::ebo<bti<n>, Xn>(detail::ebo_get<bti<n>>(static_cast<Other&&>(other)))...
0066 { }
0067
0068 template <typename ...Yn>
0069 explicit constexpr basic_tuple_impl(Yn&& ...yn)
0070 : detail::ebo<bti<n>, Xn>(static_cast<Yn&&>(yn))...
0071 { }
0072 };
0073 }
0074
0075
0076
0077
0078
0079 template <typename ...Xn>
0080 struct basic_tuple final
0081 : detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>
0082 {
0083 using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>;
0084
0085 constexpr basic_tuple() = default;
0086
0087
0088 template <typename Other, typename = typename std::enable_if<
0089 std::is_same<typename detail::decay<Other>::type, basic_tuple>::value
0090 >::type>
0091 constexpr basic_tuple(Other&& other)
0092 : Base(detail::from_other{}, static_cast<Other&&>(other))
0093 { }
0094
0095 template <typename ...Yn>
0096 explicit constexpr basic_tuple(Yn&& ...yn)
0097 : Base(static_cast<Yn&&>(yn)...)
0098 { }
0099 };
0100
0101
0102 template <typename ...Xn>
0103 struct tag_of<basic_tuple<Xn...>> {
0104 using type = basic_tuple_tag;
0105 };
0106
0107
0108
0109
0110 template <>
0111 struct unpack_impl<basic_tuple_tag> {
0112 template <std::size_t ...i, typename ...Xn, typename F>
0113 static constexpr decltype(auto)
0114 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F&& f) {
0115 return static_cast<F&&>(f)(
0116 detail::ebo_get<detail::bti<i>>(
0117 static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
0118 )...
0119 );
0120 }
0121
0122 template <std::size_t ...i, typename ...Xn, typename F>
0123 static constexpr decltype(auto)
0124 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F&& f) {
0125 return static_cast<F&&>(f)(
0126 detail::ebo_get<detail::bti<i>>(
0127 static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
0128 )...
0129 );
0130 }
0131
0132 template <std::size_t ...i, typename ...Xn, typename F>
0133 static constexpr decltype(auto)
0134 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F&& f) {
0135 return static_cast<F&&>(f)(
0136 detail::ebo_get<detail::bti<i>>(
0137 static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
0138 )...
0139 );
0140 }
0141 };
0142
0143
0144
0145
0146 template <>
0147 struct transform_impl<basic_tuple_tag> {
0148 template <std::size_t ...i, typename ...Xn, typename F>
0149 static constexpr auto
0150 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F const& f) {
0151 return hana::make_basic_tuple(
0152 f(detail::ebo_get<detail::bti<i>>(
0153 static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
0154 ))...
0155 );
0156 }
0157
0158 template <std::size_t ...i, typename ...Xn, typename F>
0159 static constexpr auto
0160 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F const& f) {
0161 return hana::make_basic_tuple(
0162 f(detail::ebo_get<detail::bti<i>>(
0163 static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
0164 ))...
0165 );
0166 }
0167
0168 template <std::size_t ...i, typename ...Xn, typename F>
0169 static constexpr auto
0170 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F const& f) {
0171 return hana::make_basic_tuple(
0172 f(detail::ebo_get<detail::bti<i>>(
0173 static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
0174 ))...
0175 );
0176 }
0177 };
0178
0179
0180
0181
0182 template <>
0183 struct at_impl<basic_tuple_tag> {
0184 template <typename Xs, typename N>
0185 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
0186 constexpr std::size_t index = N::value;
0187 return detail::ebo_get<detail::bti<index>>(static_cast<Xs&&>(xs));
0188 }
0189 };
0190
0191 template <>
0192 struct drop_front_impl<basic_tuple_tag> {
0193 template <std::size_t N, typename Xs, std::size_t ...i>
0194 static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
0195 return hana::make_basic_tuple(
0196 detail::ebo_get<detail::bti<i+N>>(static_cast<Xs&&>(xs))...
0197 );
0198 }
0199
0200 template <typename Xs, typename N>
0201 static constexpr auto apply(Xs&& xs, N const&) {
0202 constexpr std::size_t len = detail::decay<Xs>::type::size_;
0203 return drop_front_helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
0204 (N::value < len) ? len - N::value : 0
0205 >{});
0206 }
0207 };
0208
0209 template <>
0210 struct is_empty_impl<basic_tuple_tag> {
0211 template <typename ...Xs>
0212 static constexpr hana::bool_<sizeof...(Xs) == 0>
0213 apply(basic_tuple<Xs...> const&)
0214 { return {}; }
0215 };
0216
0217
0218 template <std::size_t n, typename ...Xs>
0219 constexpr decltype(auto) at_c(basic_tuple<Xs...> const& xs) {
0220 return detail::ebo_get<detail::bti<n>>(xs);
0221 }
0222
0223 template <std::size_t n, typename ...Xs>
0224 constexpr decltype(auto) at_c(basic_tuple<Xs...>& xs) {
0225 return detail::ebo_get<detail::bti<n>>(xs);
0226 }
0227
0228 template <std::size_t n, typename ...Xs>
0229 constexpr decltype(auto) at_c(basic_tuple<Xs...>&& xs) {
0230 return detail::ebo_get<detail::bti<n>>(static_cast<basic_tuple<Xs...>&&>(xs));
0231 }
0232
0233
0234
0235
0236 template <>
0237 struct Sequence<basic_tuple_tag> {
0238 static constexpr bool value = true;
0239 };
0240
0241 template <>
0242 struct make_impl<basic_tuple_tag> {
0243 template <typename ...Xn>
0244 static constexpr basic_tuple<typename detail::decay<Xn>::type...>
0245 apply(Xn&& ...xn) {
0246 return basic_tuple<typename detail::decay<Xn>::type...>{
0247 static_cast<Xn&&>(xn)...
0248 };
0249 }
0250 };
0251
0252
0253
0254
0255 template <>
0256 struct length_impl<basic_tuple_tag> {
0257 template <typename ...Xn>
0258 static constexpr auto apply(basic_tuple<Xn...> const&) {
0259 return hana::size_t<sizeof...(Xn)>{};
0260 }
0261 };
0262 }}
0263
0264 #endif