Warning, file /include/boost/pfr/detail/make_flat_tuple_of_references.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PFR_DETAIL_MAKE_FLAT_TUPLE_OF_REFERENCES_HPP
0007 #define BOOST_PFR_DETAIL_MAKE_FLAT_TUPLE_OF_REFERENCES_HPP
0008 #pragma once
0009
0010 #include <boost/pfr/detail/config.hpp>
0011
0012 #include <boost/pfr/detail/sequence_tuple.hpp>
0013 #include <boost/pfr/detail/rvalue_t.hpp>
0014 #include <boost/pfr/detail/make_integer_sequence.hpp>
0015
0016 #if !defined(BOOST_PFR_INTERFACE_UNIT)
0017 #include <utility> // metaprogramming stuff
0018 #endif
0019
0020 namespace boost { namespace pfr { namespace detail {
0021
0022 template <std::size_t Index>
0023 using size_t_ = std::integral_constant<std::size_t, Index >;
0024
0025
0026
0027 struct sequence_tuple_getter {
0028 template <std::size_t idx, typename TupleOfReferences>
0029 decltype(auto) get(TupleOfReferences&& t, size_t_<idx>) const noexcept {
0030 return sequence_tuple::get<idx>(std::forward<TupleOfReferences>(t));
0031 }
0032 };
0033
0034
0035 template <class TupleOrUserType, class Getter, std::size_t Begin, std::size_t Size>
0036 constexpr auto make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<Size>) noexcept;
0037
0038 template <class TupleOrUserType, class Getter, std::size_t Begin>
0039 constexpr sequence_tuple::tuple<> make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<0>) noexcept;
0040
0041 template <class TupleOrUserType, class Getter, std::size_t Begin>
0042 constexpr auto make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<1>) noexcept;
0043
0044 template <class... T>
0045 constexpr auto tie_as_tuple_with_references(T&... args) noexcept {
0046 return sequence_tuple::tuple<T&...>{ args... };
0047 }
0048
0049 template <class... T>
0050 constexpr decltype(auto) tie_as_tuple_with_references(detail::sequence_tuple::tuple<T...>& t) noexcept {
0051 return detail::make_flat_tuple_of_references(t, sequence_tuple_getter{}, size_t_<0>{}, size_t_<sequence_tuple::tuple<T...>::size_v>{});
0052 }
0053
0054 template <class... T>
0055 constexpr decltype(auto) tie_as_tuple_with_references(const detail::sequence_tuple::tuple<T...>& t) noexcept {
0056 return detail::make_flat_tuple_of_references(t, sequence_tuple_getter{}, size_t_<0>{}, size_t_<sequence_tuple::tuple<T...>::size_v>{});
0057 }
0058
0059 template <class Tuple1, std::size_t... I1, class Tuple2, std::size_t... I2>
0060 constexpr auto my_tuple_cat_impl(const Tuple1& t1, std::index_sequence<I1...>, const Tuple2& t2, std::index_sequence<I2...>) noexcept {
0061 return detail::tie_as_tuple_with_references(
0062 sequence_tuple::get<I1>(t1)...,
0063 sequence_tuple::get<I2>(t2)...
0064 );
0065 }
0066
0067 template <class Tuple1, class Tuple2>
0068 constexpr auto my_tuple_cat(const Tuple1& t1, const Tuple2& t2) noexcept {
0069 return detail::my_tuple_cat_impl(
0070 t1, detail::make_index_sequence< Tuple1::size_v >{},
0071 t2, detail::make_index_sequence< Tuple2::size_v >{}
0072 );
0073 }
0074
0075 template <class TupleOrUserType, class Getter, std::size_t Begin, std::size_t Size>
0076 constexpr auto make_flat_tuple_of_references(TupleOrUserType& t, const Getter& g, size_t_<Begin>, size_t_<Size>) noexcept {
0077 constexpr std::size_t next_size = Size / 2;
0078 return detail::my_tuple_cat(
0079 detail::make_flat_tuple_of_references(t, g, size_t_<Begin>{}, size_t_<next_size>{}),
0080 detail::make_flat_tuple_of_references(t, g, size_t_<Begin + Size / 2>{}, size_t_<Size - next_size>{})
0081 );
0082 }
0083
0084 template <class TupleOrUserType, class Getter, std::size_t Begin>
0085 constexpr sequence_tuple::tuple<> make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<0>) noexcept {
0086 return {};
0087 }
0088
0089 template <class TupleOrUserType, class Getter, std::size_t Begin>
0090 constexpr auto make_flat_tuple_of_references(TupleOrUserType& t, const Getter& g, size_t_<Begin>, size_t_<1>) noexcept {
0091 return detail::tie_as_tuple_with_references(
0092 g.get(t, size_t_<Begin>{})
0093 );
0094 }
0095
0096 }}}
0097
0098 #endif