File indexing completed on 2025-01-30 09:43:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_UNPACK_HPP
0011 #define BOOST_HANA_UNPACK_HPP
0012
0013 #include <boost/hana/fwd/unpack.hpp>
0014
0015 #include <boost/hana/accessors.hpp>
0016 #include <boost/hana/at.hpp>
0017 #include <boost/hana/concept/foldable.hpp>
0018 #include <boost/hana/concept/iterable.hpp>
0019 #include <boost/hana/concept/struct.hpp>
0020 #include <boost/hana/config.hpp>
0021 #include <boost/hana/core/dispatch.hpp>
0022 #include <boost/hana/first.hpp>
0023 #include <boost/hana/functional/partial.hpp>
0024 #include <boost/hana/fwd/fold_left.hpp>
0025 #include <boost/hana/length.hpp>
0026 #include <boost/hana/pair.hpp>
0027 #include <boost/hana/second.hpp>
0028
0029 #include <cstddef>
0030 #include <utility>
0031
0032
0033 namespace boost { namespace hana {
0034
0035 template <typename Xs, typename F>
0036 constexpr decltype(auto) unpack_t::operator()(Xs&& xs, F&& f) const {
0037 using S = typename hana::tag_of<Xs>::type;
0038 using Unpack = BOOST_HANA_DISPATCH_IF(unpack_impl<S>,
0039 hana::Foldable<S>::value
0040 );
0041
0042 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0043 static_assert(hana::Foldable<S>::value,
0044 "hana::unpack(xs, f) requires 'xs' to be Foldable");
0045 #endif
0046
0047 return Unpack::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f));
0048 }
0049
0050
0051 template <typename T, bool condition>
0052 struct unpack_impl<T, when<condition>> : default_ {
0053 template <typename Xs, typename F>
0054 static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
0055 return hana::fold_left(static_cast<Xs&&>(xs),
0056 static_cast<F&&>(f),
0057 hana::partial)();
0058 }
0059 };
0060
0061 template <typename It>
0062 struct unpack_impl<It, when<
0063 hana::Iterable<It>::value && !is_default<length_impl<It>>::value
0064 >> {
0065 template <typename Xs, typename F, std::size_t ...i>
0066 static constexpr decltype(auto)
0067 unpack_helper(Xs&& xs, F&& f, std::index_sequence<i...>) {
0068 return static_cast<F&&>(f)(hana::at_c<i>(static_cast<Xs&&>(xs))...);
0069 }
0070
0071 template <typename Xs, typename F>
0072 static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
0073 constexpr std::size_t N = decltype(hana::length(xs))::value;
0074 return unpack_helper(static_cast<Xs&&>(xs), static_cast<F&&>(f),
0075 std::make_index_sequence<N>{});
0076 }
0077 };
0078
0079 template <typename T, std::size_t N>
0080 struct unpack_impl<T[N]> {
0081 template <typename Xs, typename F, std::size_t ...i>
0082 static constexpr decltype(auto)
0083 unpack_helper(Xs&& xs, F&& f, std::index_sequence<i...>) {
0084 return static_cast<F&&>(f)(static_cast<Xs&&>(xs)[i]...);
0085 }
0086
0087 template <typename Xs, typename F>
0088 static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
0089 return unpack_impl::unpack_helper(static_cast<Xs&&>(xs),
0090 static_cast<F&&>(f),
0091 std::make_index_sequence<N>{});
0092 }
0093 };
0094
0095
0096
0097
0098 template <typename T>
0099 struct unpack_impl<T, when<hana::Product<T>::value>> {
0100 template <typename P, typename F>
0101 static constexpr decltype(auto) apply(P&& p, F&& f) {
0102 return static_cast<F&&>(f)(
0103 hana::first(static_cast<P&&>(p)),
0104 hana::second(static_cast<P&&>(p))
0105 );
0106 }
0107 };
0108
0109
0110
0111
0112 namespace struct_detail {
0113
0114
0115
0116 struct almost_demux {
0117 template <typename F, typename Udt, typename ...Members>
0118 constexpr decltype(auto)
0119 operator()(F&& f, Udt&& udt, Members&& ...g) const {
0120 return static_cast<F&&>(f)(hana::make_pair(
0121 hana::first(static_cast<Members&&>(g)),
0122 hana::second(static_cast<Members&&>(g))
0123 (static_cast<Udt&&>(udt))
0124 )...);
0125 }
0126 };
0127 }
0128
0129 template <typename S>
0130 struct unpack_impl<S, when<hana::Struct<S>::value>> {
0131 template <typename Udt, typename F>
0132 static constexpr decltype(auto) apply(Udt&& udt, F&& f) {
0133 return hana::unpack(hana::accessors<S>(),
0134 hana::partial(struct_detail::almost_demux{},
0135 static_cast<F&&>(f),
0136 static_cast<Udt&&>(udt)));
0137 }
0138 };
0139 }}
0140
0141 #endif