File indexing completed on 2025-01-18 09:43:38
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PFR_CORE_HPP
0007 #define BOOST_PFR_CORE_HPP
0008 #pragma once
0009
0010 #include <boost/pfr/detail/config.hpp>
0011
0012 #include <boost/pfr/detail/core.hpp>
0013
0014 #include <boost/pfr/detail/sequence_tuple.hpp>
0015 #include <boost/pfr/detail/stdtuple.hpp>
0016 #include <boost/pfr/detail/for_each_field_impl.hpp>
0017 #include <boost/pfr/detail/make_integer_sequence.hpp>
0018 #include <boost/pfr/detail/tie_from_structure_tuple.hpp>
0019
0020 #include <type_traits>
0021 #include <utility> // metaprogramming stuff
0022
0023 #include <boost/pfr/tuple_size.hpp>
0024
0025
0026
0027
0028
0029
0030 namespace boost { namespace pfr {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 template <std::size_t I, class T>
0048 constexpr decltype(auto) get(const T& val) noexcept {
0049 return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
0050 }
0051
0052
0053 template <std::size_t I, class T>
0054 constexpr decltype(auto) get(T& val
0055 #if !BOOST_PFR_USE_CPP17
0056 , std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
0057 #endif
0058 ) noexcept {
0059 return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
0060 }
0061
0062 #if !BOOST_PFR_USE_CPP17
0063
0064 template <std::size_t I, class T>
0065 constexpr auto get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
0066 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
0067 return 0;
0068 }
0069 #endif
0070
0071
0072
0073 template <std::size_t I, class T>
0074 constexpr auto get(T&& val, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
0075 return std::move(detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) ));
0076 }
0077
0078
0079
0080 template <class U, class T>
0081 constexpr const U& get(const T& val) noexcept {
0082 return detail::sequence_tuple::get_by_type_impl<const U&>( detail::tie_as_tuple(val) );
0083 }
0084
0085
0086
0087 template <class U, class T>
0088 constexpr U& get(T& val
0089 #if !BOOST_PFR_USE_CPP17
0090 , std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
0091 #endif
0092 ) noexcept {
0093 return detail::sequence_tuple::get_by_type_impl<U&>( detail::tie_as_tuple(val) );
0094 }
0095
0096 #if !BOOST_PFR_USE_CPP17
0097
0098 template <class U, class T>
0099 constexpr U& get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
0100 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
0101 return 0;
0102 }
0103 #endif
0104
0105
0106
0107 template <class U, class T>
0108 constexpr U&& get(T&& val, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
0109 return std::move(detail::sequence_tuple::get_by_type_impl<U&>( detail::tie_as_tuple(val) ));
0110 }
0111
0112
0113
0114
0115
0116
0117
0118
0119 template <std::size_t I, class T>
0120 using tuple_element = detail::sequence_tuple::tuple_element<I, decltype( ::boost::pfr::detail::tie_as_tuple(std::declval<T&>()) ) >;
0121
0122
0123
0124
0125
0126
0127
0128
0129 template <std::size_t I, class T>
0130 using tuple_element_t = typename tuple_element<I, T>::type;
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 template <class T>
0143 constexpr auto structure_to_tuple(const T& val) noexcept {
0144 return detail::make_stdtuple_from_tietuple(
0145 detail::tie_as_tuple(val),
0146 detail::make_index_sequence< tuple_size_v<T> >()
0147 );
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 template <class T>
0168 constexpr auto structure_tie(const T& val) noexcept {
0169 return detail::make_conststdtiedtuple_from_tietuple(
0170 detail::tie_as_tuple(const_cast<T&>(val)),
0171 detail::make_index_sequence< tuple_size_v<T> >()
0172 );
0173 }
0174
0175
0176
0177 template <class T>
0178 constexpr auto structure_tie(T& val
0179 #if !BOOST_PFR_USE_CPP17
0180 , std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
0181 #endif
0182 ) noexcept {
0183 return detail::make_stdtiedtuple_from_tietuple(
0184 detail::tie_as_tuple(val),
0185 detail::make_index_sequence< tuple_size_v<T> >()
0186 );
0187 }
0188
0189 #if !BOOST_PFR_USE_CPP17
0190
0191 template <class T>
0192 constexpr auto structure_tie(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
0193 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17");
0194 return 0;
0195 }
0196 #endif
0197
0198
0199
0200 template <class T>
0201 constexpr auto structure_tie(T&&, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
0202 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on rvalue references is forbidden");
0203 return 0;
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 template <class T, class F>
0223 constexpr void for_each_field(T&& value, F&& func) {
0224 constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<std::remove_reference_t<T>>();
0225
0226 ::boost::pfr::detail::for_each_field_dispatcher(
0227 value,
0228 [f = std::forward<F>(func)](auto&& t) mutable {
0229
0230 constexpr std::size_t fields_count_val_in_lambda
0231 = boost::pfr::detail::fields_count<std::remove_reference_t<T>>();
0232
0233 ::boost::pfr::detail::for_each_field_impl(
0234 t,
0235 std::forward<F>(f),
0236 detail::make_index_sequence<fields_count_val_in_lambda>{},
0237 std::is_rvalue_reference<T&&>{}
0238 );
0239 },
0240 detail::make_index_sequence<fields_count_val>{}
0241 );
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 template <typename... Elements>
0259 constexpr detail::tie_from_structure_tuple<Elements...> tie_from_structure(Elements&... args) noexcept {
0260 return detail::tie_from_structure_tuple<Elements...>(args...);
0261 }
0262
0263 }}
0264
0265 #endif