File tree Expand file tree Collapse file tree 5 files changed +67
-1
lines changed Expand file tree Collapse file tree 5 files changed +67
-1
lines changed Original file line number Diff line number Diff line change @@ -281,7 +281,7 @@ for (const auto& f : rfl::fields<Person>()) {
281
281
}
282
282
```
283
283
284
- You can also create a view and then access these fields using `std::get` or `rfl::get`:
284
+ You can also create a view and then access these fields using `std::get` or `rfl::get`, or iterate over the fields at compile-time :
285
285
286
286
```cpp
287
287
auto lisa = Person{.first_name = "Lisa", .last_name = "Simpson", .age = 8};
@@ -298,6 +298,11 @@ const auto view = rfl::to_view(lisa);
298
298
*view.get<"age">() = 0;
299
299
*rfl::get<0>(view) = "Maggie";
300
300
*rfl::get<"first_name">(view) = "Maggie";
301
+
302
+ view.apply([](const auto& f) {
303
+ // f is a an rfl::Field pointing to the original field.
304
+ std::cout << f.name() << ": " << rfl::json::write(*f.value()) << std::endl;
305
+ });
301
306
```
302
307
303
308
It also possible to replace fields:
Original file line number Diff line number Diff line change @@ -95,6 +95,25 @@ const auto first_name = person.template get<"firstName">();
95
95
const auto first_name = rfl::get<"firstName">(person);
96
96
```
97
97
98
+ Fields can also be iterated over at compile-time using the ` apply() ` method:
99
+
100
+ ``` cpp
101
+ auto person = rfl::Field<" first_name" , std::string>(" Bart" ) *
102
+ rfl::Field<" last_name" , std::string>(" Simpson" );
103
+
104
+ person.apply([](const auto & f) {
105
+ auto field_name = f.name();
106
+ const auto& value = * f.value();
107
+ });
108
+
109
+ person.apply([]<typename Field>(Field& f) {
110
+ // The field name can also be obtained as a compile-time constant.
111
+ constexpr auto field_name = Field::name();
112
+ using field_pointer_type = typename Field::Type;
113
+ field_pointer_type* value = f.value();
114
+ });
115
+ ```
116
+
98
117
### ` rfl::replace `
99
118
100
119
` rfl::replace ` works for ` rfl::NamedTuple ` as well:
Original file line number Diff line number Diff line change @@ -62,6 +62,9 @@ struct Field {
62
62
// / The name of the field, for internal use.
63
63
constexpr static const internal::StringLiteral name_ = _name;
64
64
65
+ // / The name of the field.
66
+ constexpr static std::string_view name () { return name_.string_view (); }
67
+
65
68
// / Returns the underlying object.
66
69
const Type& get () const { return value_; }
67
70
Original file line number Diff line number Diff line change @@ -210,6 +210,26 @@ class NamedTuple {
210
210
return rfl::make_field<_field_name>(rfl::get<_field_name>(*this ));
211
211
}
212
212
213
+ // / Invokes a callable object once for each field in order.
214
+ template <typename F>
215
+ void apply (F&& f) {
216
+ std::apply (
217
+ [&f]<typename ... AFields>(AFields&&... fields) {
218
+ ((f (std::forward<AFields>(fields))), ...);
219
+ },
220
+ fields ());
221
+ }
222
+
223
+ // / Invokes a callable object once for each field in order.
224
+ template <typename F>
225
+ void apply (F&& f) const {
226
+ std::apply (
227
+ [&f]<typename ... AFields>(AFields&&... fields) {
228
+ ((f (std::forward<AFields>(fields))), ...);
229
+ },
230
+ fields ());
231
+ }
232
+
213
233
// / Copy assignment operator.
214
234
NamedTuple<FieldTypes...>& operator =(
215
235
const NamedTuple<FieldTypes...>& _other) = default ;
Original file line number Diff line number Diff line change 4
4
#include < rfl/json.hpp>
5
5
#include < source_location>
6
6
#include < string>
7
+ #include < type_traits>
7
8
#include < vector>
8
9
9
10
#include " test_replace.hpp"
@@ -30,5 +31,23 @@ void test() {
30
31
31
32
write_and_read (lisa,
32
33
R"( {"first_name":"Maggie","last_name":"Simpson","age":0})" );
34
+
35
+ view.apply ([]<typename Field>(const Field& field) {
36
+ using field_type = std::remove_pointer_t <typename Field::Type>;
37
+ if constexpr (Field::name () == " age" ) {
38
+ static_assert (std::is_same_v<field_type, int >);
39
+ } else {
40
+ static_assert (std::is_same_v<field_type, std::string>);
41
+ }
42
+ });
43
+
44
+ rfl::to_view (lisa).apply ([](auto field) {
45
+ if constexpr (decltype (field)::name () == " first_name" ) {
46
+ *field.value () = " Bart" ;
47
+ }
48
+ });
49
+
50
+ write_and_read (lisa,
51
+ R"( {"first_name":"Bart","last_name":"Simpson","age":0})" );
33
52
}
34
53
} // namespace test_view
You can’t perform that action at this time.
0 commit comments