3
3
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4
4
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
5
6
- #ifndef BOOST_PFR_PRECISE_CORE_HPP
7
- #define BOOST_PFR_PRECISE_CORE_HPP
6
+ #ifndef BOOST_PFR_CORE_HPP
7
+ #define BOOST_PFR_CORE_HPP
8
8
#pragma once
9
9
10
10
#include < boost/pfr/detail/config.hpp>
11
11
12
- #include < type_traits>
13
- #include < utility> // metaprogramming stuff
12
+ #include < boost/pfr/detail/core.hpp>
14
13
15
14
#include < boost/pfr/detail/sequence_tuple.hpp>
16
15
#include < boost/pfr/detail/stdtuple.hpp>
17
16
#include < boost/pfr/detail/for_each_field_impl.hpp>
18
17
#include < boost/pfr/detail/make_integer_sequence.hpp>
18
+ #include < boost/pfr/detail/tie_from_structure_tuple.hpp>
19
19
20
- #include < boost/pfr/precise/tuple_size.hpp>
21
- #if BOOST_PFR_USE_CPP17
22
- # include < boost/pfr/detail/core17.hpp>
23
- #else
24
- # include < boost/pfr/detail/core14.hpp>
25
- #endif
20
+ #include < type_traits>
21
+ #include < utility> // metaprogramming stuff
26
22
27
- #include < boost/pfr/detail/tie_from_structure_tuple.hpp>
23
+ #include < boost/pfr/tuple_size.hpp>
24
+
25
+ // / \file boost/pfr/core.hpp
26
+ // / Contains all the basic tuple-like interfaces \forcedlink{get}, \forcedlink{tuple_size}, \forcedlink{tuple_element_t}, and others.
27
+ // /
28
+ // / \b Synopsis:
28
29
29
30
namespace boost { namespace pfr {
30
31
31
- // / \brief Returns reference or const reference to a field with index `I` in aggregate T.
32
- // /
33
- // / \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
32
+ // / \brief Returns reference or const reference to a field with index `I` in \aggregate `val`.
34
33
// /
35
34
// / \b Example:
36
35
// / \code
@@ -47,38 +46,52 @@ constexpr decltype(auto) get(const T& val) noexcept {
47
46
48
47
// / \overload get
49
48
template <std::size_t I, class T >
50
- constexpr decltype (auto ) get(T& val) noexcept {
49
+ constexpr decltype (auto ) get(T& val
50
+ #if !BOOST_PFR_USE_CPP17
51
+ , std::enable_if_t <std::is_assignable<T, T>::value>* = nullptr
52
+ #endif
53
+ ) noexcept {
51
54
return detail::sequence_tuple::get<I>( detail::tie_as_tuple (val) );
52
55
}
53
56
57
+ #if !BOOST_PFR_USE_CPP17
58
+ // / \overload get
59
+ template <std::size_t I, class T >
60
+ constexpr auto get (T&, std::enable_if_t <!std::is_assignable<T, T>::value>* = nullptr ) noexcept {
61
+ static_assert (sizeof (T) && false , " ====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17" );
62
+ return 0 ;
63
+ }
64
+ #endif
54
65
55
- // / \brief `tuple_element` has a `typedef type-of-a-field-with-index-I-in-aggregate-T type;`
56
- // /
57
- // / \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
66
+
67
+ // / \overload get
68
+ template <std::size_t I, class T >
69
+ constexpr auto get (T&& val, std::enable_if_t < std::is_rvalue_reference<T&&>::value>* = 0 ) noexcept {
70
+ return std::move (detail::sequence_tuple::get<I>( detail::tie_as_tuple (val) ));
71
+ }
72
+
73
+
74
+ // / \brief `tuple_element` has a member typedef `type` that returns the type of a field with index I in \aggregate T.
58
75
// /
59
76
// / \b Example:
60
77
// / \code
61
- // / std::vector< boost::pfr::tuple_element<0, my_structure>::type > v;
78
+ // / std::vector< boost::pfr::tuple_element<0, my_structure>::type > v;
62
79
// / \endcode
63
80
template <std::size_t I, class T >
64
81
using tuple_element = detail::sequence_tuple::tuple_element<I, decltype( ::boost::pfr::detail::tie_as_tuple(std::declval<T&>()) ) >;
65
82
66
83
67
- // / \brief Type of a field with index `I` in aggregate `T`.
68
- // /
69
- // / \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
84
+ // / \brief Type of a field with index `I` in \aggregate `T`.
70
85
// /
71
86
// / \b Example:
72
87
// / \code
73
- // / std::vector< boost::pfr::tuple_element_t<0, my_structure> > v;
88
+ // / std::vector< boost::pfr::tuple_element_t<0, my_structure> > v;
74
89
// / \endcode
75
90
template <std::size_t I, class T >
76
91
using tuple_element_t = typename tuple_element<I, T>::type;
77
92
78
93
79
- // / \brief Creates an `std::tuple` from an aggregate T.
80
- // /
81
- // / \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
94
+ // / \brief Creates a `std::tuple` from fields of an \aggregate `val`.
82
95
// /
83
96
// / \b Example:
84
97
// / \code
@@ -96,33 +109,67 @@ constexpr auto structure_to_tuple(const T& val) noexcept {
96
109
}
97
110
98
111
99
- // / \brief Creates an ` std::tuple` with lvalue references to fields of an aggregate T .
112
+ // / \brief std::tie` like function that ties fields of a structure .
100
113
// /
101
- // / \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole} .
114
+ // / \returns a `std::tuple` with lvalue and const lvalue references to fields of an \aggregate `val` .
102
115
// /
103
116
// / \b Example:
104
117
// / \code
118
+ // / void foo(const int&, const short&);
105
119
// / struct my_struct { int i, short s; };
120
+ // /
121
+ // / const my_struct const_s{1, 2};
122
+ // / std::apply(foo, structure_tie(const_s));
123
+ // /
106
124
// / my_struct s;
107
125
// / structure_tie(s) = std::tuple<int, short>{10, 11};
108
126
// / assert(s.s == 11);
109
127
// / \endcode
110
128
template <class T >
111
- constexpr auto structure_tie (T& val) noexcept {
129
+ constexpr auto structure_tie (const T& val) noexcept {
130
+ return detail::make_conststdtiedtuple_from_tietuple (
131
+ detail::tie_as_tuple (const_cast <T&>(val)),
132
+ detail::make_index_sequence< tuple_size_v<T> >()
133
+ );
134
+ }
135
+
136
+
137
+ // / \overload structure_tie
138
+ template <class T >
139
+ constexpr auto structure_tie (T& val
140
+ #if !BOOST_PFR_USE_CPP17
141
+ , std::enable_if_t <std::is_assignable<T, T>::value>* = nullptr
142
+ #endif
143
+ ) noexcept {
112
144
return detail::make_stdtiedtuple_from_tietuple (
113
145
detail::tie_as_tuple (val),
114
146
detail::make_index_sequence< tuple_size_v<T> >()
115
147
);
116
148
}
117
149
150
+ #if !BOOST_PFR_USE_CPP17
151
+ // / \overload structure_tie
152
+ template <class T >
153
+ constexpr auto structure_tie (T&, std::enable_if_t <!std::is_assignable<T, T>::value>* = nullptr ) noexcept {
154
+ static_assert (sizeof (T) && false , " ====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17" );
155
+ return 0 ;
156
+ }
157
+ #endif
158
+
159
+
160
+ // / \overload structure_tie
161
+ template <class T >
162
+ constexpr auto structure_tie (T&&, std::enable_if_t < std::is_rvalue_reference<T&&>::value>* = 0 ) noexcept {
163
+ static_assert (sizeof (T) && false , " ====================> Boost.PFR: Calling boost::pfr::structure_tie on rvalue references is forbidden" );
164
+ return 0 ;
165
+ }
166
+
118
167
// / Calls `func` for each field of a `value`.
119
168
// /
120
- // / \b Requires: C++17 or \constexprinit{C++14 constexpr aggregate intializable type}.
121
- // /
122
169
// / \param func must have one of the following signatures:
123
170
// / * any_return_type func(U&& field) // field of value is perfect forwarded to function
124
171
// / * any_return_type func(U&& field, std::size_t i)
125
- // / * any_return_type func(U&& value, I i) // Here I is an `std::integral_constant<size_t, field_index>`
172
+ // / * any_return_type func(U&& value, I i) // Here I is an `std::integral_constant<size_t, field_index>`
126
173
// /
127
174
// / \param value To each field of this variable will be the `func` applied.
128
175
// /
@@ -140,7 +187,7 @@ void for_each_field(T&& value, F&& func) {
140
187
::boost::pfr::detail::for_each_field_dispatcher (
141
188
value,
142
189
[f = std::forward<F>(func)](auto && t) mutable {
143
- // MSVC related workaround. It's lambdas do not capture constexprs.
190
+ // MSVC related workaround. Its lambdas do not capture constexprs.
144
191
constexpr std::size_t fields_count_val_in_lambda
145
192
= boost::pfr::detail::fields_count<std::remove_reference_t <T>>();
146
193
@@ -155,8 +202,10 @@ void for_each_field(T&& value, F&& func) {
155
202
);
156
203
}
157
204
158
- // / \brief Create a tuple of lvalue references capable of de-structuring
159
- // / assignment from fields of an aggregate T.
205
+ // / \brief std::tie-like function that allows assigning to tied values from aggregates.
206
+ // /
207
+ // / \returns an object with lvalue references to `args...`; on assignment of an \aggregate value to that
208
+ // / object each field of an aggregate is assigned to the corresponding `args...` reference.
160
209
// /
161
210
// / \b Example:
162
211
// / \code
@@ -174,4 +223,4 @@ constexpr detail::tie_from_structure_tuple<Elements...> tie_from_structure(Eleme
174
223
175
224
}} // namespace boost::pfr
176
225
177
- #endif // BOOST_PFR_PRECISE_CORE_HPP
226
+ #endif // BOOST_PFR_CORE_HPP
0 commit comments