File indexing completed on 2025-09-16 08:42:25
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.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 BOOST_PFR_BEGIN_MODULE_EXPORT
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 template <std::size_t I, class T>
0050 constexpr decltype(auto) get(const T& val) noexcept {
0051 return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
0052 }
0053
0054
0055 template <std::size_t I, class T>
0056 constexpr decltype(auto) get(T& val
0057 #if !BOOST_PFR_USE_CPP17
0058 , std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
0059 #endif
0060 ) noexcept {
0061 return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
0062 }
0063
0064 #if !BOOST_PFR_USE_CPP17
0065
0066 template <std::size_t I, class T>
0067 constexpr auto get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
0068 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
0069 return 0;
0070 }
0071 #endif
0072
0073
0074
0075 template <std::size_t I, class T>
0076 constexpr auto get(T&& val, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
0077 return std::move(detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) ));
0078 }
0079
0080
0081
0082 template <class U, class T>
0083 constexpr const U& get(const T& val) noexcept {
0084 return detail::sequence_tuple::get_by_type_impl<const U&>( detail::tie_as_tuple(val) );
0085 }
0086
0087
0088
0089 template <class U, class T>
0090 constexpr U& get(T& val
0091 #if !BOOST_PFR_USE_CPP17
0092 , std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
0093 #endif
0094 ) noexcept {
0095 return detail::sequence_tuple::get_by_type_impl<U&>( detail::tie_as_tuple(val) );
0096 }
0097
0098 #if !BOOST_PFR_USE_CPP17
0099
0100 template <class U, class T>
0101 constexpr U& get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
0102 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
0103 return 0;
0104 }
0105 #endif
0106
0107
0108
0109 template <class U, class T>
0110 constexpr U&& get(T&& val, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
0111 return std::move(detail::sequence_tuple::get_by_type_impl<U&>( detail::tie_as_tuple(val) ));
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121 template <std::size_t I, class T>
0122 using tuple_element = detail::sequence_tuple::tuple_element<I, decltype( ::boost::pfr::detail::tie_as_tuple(std::declval<T&>()) ) >;
0123
0124
0125
0126
0127
0128
0129
0130
0131 template <std::size_t I, class T>
0132 using tuple_element_t = typename tuple_element<I, T>::type;
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 template <class T>
0145 constexpr auto structure_to_tuple(const T& val) {
0146 return detail::make_stdtuple_from_tietuple(
0147 detail::tie_as_tuple(val),
0148 detail::make_index_sequence< tuple_size_v<T> >()
0149 );
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 template <class T>
0170 constexpr auto structure_tie(const T& val) noexcept {
0171 return detail::make_conststdtiedtuple_from_tietuple(
0172 detail::tie_as_tuple(const_cast<T&>(val)),
0173 detail::make_index_sequence< tuple_size_v<T> >()
0174 );
0175 }
0176
0177
0178
0179 template <class T>
0180 constexpr auto structure_tie(T& val
0181 #if !BOOST_PFR_USE_CPP17
0182 , std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
0183 #endif
0184 ) noexcept {
0185 return detail::make_stdtiedtuple_from_tietuple(
0186 detail::tie_as_tuple(val),
0187 detail::make_index_sequence< tuple_size_v<T> >()
0188 );
0189 }
0190
0191 #if !BOOST_PFR_USE_CPP17
0192
0193 template <class T>
0194 constexpr auto structure_tie(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
0195 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17");
0196 return 0;
0197 }
0198 #endif
0199
0200
0201
0202 template <class T>
0203 constexpr auto structure_tie(T&&, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
0204 static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on rvalue references is forbidden");
0205 return 0;
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 template <class T, class F>
0225 constexpr void for_each_field(T&& value, F&& func) {
0226 return ::boost::pfr::detail::for_each_field(std::forward<T>(value), std::forward<F>(func));
0227 }
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 template <typename... Elements>
0244 constexpr detail::tie_from_structure_tuple<Elements...> tie_from_structure(Elements&... args) noexcept {
0245 return detail::tie_from_structure_tuple<Elements...>(args...);
0246 }
0247
0248 BOOST_PFR_END_MODULE_EXPORT
0249
0250 }}
0251
0252 #endif