Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:43:18

0001 // Copyright (c) 2016-2025 Antony Polukhin
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 #ifdef BOOST_PFR_HAS_STD_MODULE
0013 import std;
0014 #else
0015 #include <utility>      // metaprogramming stuff
0016 #endif
0017 
0018 #include <boost/pfr/detail/sequence_tuple.hpp>
0019 #include <boost/pfr/detail/rvalue_t.hpp>
0020 #include <boost/pfr/detail/make_integer_sequence.hpp>
0021 
0022 
0023 namespace boost { namespace pfr { namespace detail {
0024 
0025 template <std::size_t Index>
0026 using size_t_ = std::integral_constant<std::size_t, Index >;
0027 
0028 // Helper: Make a "getter" object corresponding to built-in tuple::get
0029 // For user-defined structures, the getter should be "offset_based_getter"
0030 struct sequence_tuple_getter {
0031   template <std::size_t idx, typename TupleOfReferences>
0032   decltype(auto) get(TupleOfReferences&& t, size_t_<idx>) const noexcept {
0033     return sequence_tuple::get<idx>(std::forward<TupleOfReferences>(t));
0034   }
0035 };
0036 
0037 
0038 template <class TupleOrUserType, class Getter, std::size_t Begin, std::size_t Size>
0039 constexpr auto make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<Size>) noexcept;
0040 
0041 template <class TupleOrUserType, class Getter, std::size_t Begin>
0042 constexpr sequence_tuple::tuple<> make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<0>) noexcept;
0043 
0044 template <class TupleOrUserType, class Getter, std::size_t Begin>
0045 constexpr auto make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<1>) noexcept;
0046 
0047 template <class... T>
0048 constexpr auto tie_as_tuple_with_references(T&... args) noexcept {
0049     return sequence_tuple::tuple<T&...>{ args... };
0050 }
0051 
0052 template <class... T>
0053 constexpr decltype(auto) tie_as_tuple_with_references(detail::sequence_tuple::tuple<T...>& t) noexcept {
0054     return detail::make_flat_tuple_of_references(t, sequence_tuple_getter{}, size_t_<0>{}, size_t_<sequence_tuple::tuple<T...>::size_v>{});
0055 }
0056 
0057 template <class... T>
0058 constexpr decltype(auto) tie_as_tuple_with_references(const detail::sequence_tuple::tuple<T...>& t) noexcept {
0059     return detail::make_flat_tuple_of_references(t, sequence_tuple_getter{}, size_t_<0>{}, size_t_<sequence_tuple::tuple<T...>::size_v>{});
0060 }
0061 
0062 template <class Tuple1, std::size_t... I1, class Tuple2, std::size_t... I2>
0063 constexpr auto my_tuple_cat_impl(const Tuple1& t1, std::index_sequence<I1...>, const Tuple2& t2, std::index_sequence<I2...>) noexcept {
0064     return detail::tie_as_tuple_with_references(
0065         sequence_tuple::get<I1>(t1)...,
0066         sequence_tuple::get<I2>(t2)...
0067     );
0068 }
0069 
0070 template <class Tuple1, class Tuple2>
0071 constexpr auto my_tuple_cat(const Tuple1& t1, const Tuple2& t2) noexcept {
0072     return detail::my_tuple_cat_impl(
0073         t1, detail::make_index_sequence< Tuple1::size_v >{},
0074         t2, detail::make_index_sequence< Tuple2::size_v >{}
0075     );
0076 }
0077 
0078 template <class TupleOrUserType, class Getter, std::size_t Begin, std::size_t Size>
0079 constexpr auto make_flat_tuple_of_references(TupleOrUserType& t, const Getter& g, size_t_<Begin>, size_t_<Size>) noexcept {
0080     constexpr std::size_t next_size = Size / 2;
0081     return detail::my_tuple_cat(
0082         detail::make_flat_tuple_of_references(t, g, size_t_<Begin>{}, size_t_<next_size>{}),
0083         detail::make_flat_tuple_of_references(t, g, size_t_<Begin + Size / 2>{}, size_t_<Size - next_size>{})
0084     );
0085 }
0086 
0087 template <class TupleOrUserType, class Getter, std::size_t Begin>
0088 constexpr sequence_tuple::tuple<> make_flat_tuple_of_references(TupleOrUserType&, const Getter&, size_t_<Begin>, size_t_<0>) noexcept {
0089     return {};
0090 }
0091 
0092 template <class TupleOrUserType, class Getter, std::size_t Begin>
0093 constexpr auto make_flat_tuple_of_references(TupleOrUserType& t, const Getter& g, size_t_<Begin>, size_t_<1>) noexcept {
0094     return detail::tie_as_tuple_with_references(
0095         g.get(t, size_t_<Begin>{})
0096     );
0097 }
0098 
0099 }}} // namespace boost::pfr::detail
0100 
0101 #endif // BOOST_PFR_DETAIL_MAKE_FLAT_TUPLE_OF_REFERENCES_HPP