1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
// Copyright 2016-2025 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
#include <cassert>
#include <iostream>
#include <unordered_set>
#include <set>
#include <boost/pfr.hpp>
#include <boost/type_index.hpp>
// boost-no-inspect
void test_examples() {
#if BOOST_PFR_USE_CPP17
{
//[pfr_quick_examples_ops
// Assert equality.
// Note that the equality operator for structure is not defined.
struct test {
std::string f1;
std::string_view f2;
};
assert(
boost::pfr::eq(test{"aaa", "zomg"}, test{"aaa", "zomg"})
);
//]
}
#endif
{
//[pfr_quick_examples_for_each
// Increment each field of the variable on 1 and
// output the content of the variable.
struct test {
int f1;
long f2;
};
test var{42, 43};
boost::pfr::for_each_field(var, [](auto& field) {
field += 1;
});
// Outputs: {43, 44}
std::cout << boost::pfr::io(var);
//]
}
{
//[pfr_quick_examples_for_each_idx
// Iterate over fields of a variable and output index and
// type of a variable.
struct tag0{};
struct tag1{};
struct sample {
tag0 a;
tag1 b;
};
// Outputs:
// 0: tag0
// 1: tag1
boost::pfr::for_each_field(sample{}, [](const auto& field, std::size_t idx) {
std::cout << '\n' << idx << ": "
<< boost::typeindex::type_id_runtime(field);
});
//]
}
// Disabling for MSVC as it gives a hard error on using local types:
//
// error C7631:
// 'boost::pfr::detail::do_not_use_PFR_with_local_types<test_examples::sample>':
// variable with internal linkage declared but not defined
#if BOOST_PFR_CORE_NAME_ENABLED && BOOST_PFR_USE_CPP17 && !defined(_MSC_VER)
{
//[pfr_quick_examples_for_each_with_name
// Print the name and value
// of each element of the structure
struct test {
int n;
std::string str;
};
test var{42, "Hello, World!"};
// Outputs:
// n: 42
// str: Hello, World!
boost::pfr::for_each_field_with_name(var,
[](std::string_view name, const auto& value) {
std::cout << name << ": " << value << std::endl;
});
//]
}
#endif
{
//[pfr_quick_examples_tuple_size
// Getting fields count of some structure
struct some { int a,b,c,d,e; };
std::cout << "Fields count in structure: "
<< boost::pfr::tuple_size<some>::value // Outputs: 5
<< '\n';
//]
}
{
//[pfr_quick_examples_get
// Get field by index/type and assign new value to that field
struct sample {
char c;
float f;
};
sample var{};
boost::pfr::get<1>(var) = 42.01f;
boost::pfr::get<char>(var) = 'A';
std::cout << var.c << var.f; // Outputs: A 42.01
//]
}
// Disabling for MSVC as it gives a hard error on using local types:
//
// error C7631:
// 'boost::pfr::detail::do_not_use_PFR_with_local_types<test_examples::sample>':
// variable with internal linkage declared but not defined
#if BOOST_PFR_CORE_NAME_ENABLED && BOOST_PFR_USE_CPP17 && !defined(_MSC_VER)
{
//[pfr_quick_examples_get_name
// Get name of field by index
struct sample {
int f_int;
long f_long;
};
std::cout << boost::pfr::get_name<0, sample>()
<< boost::pfr::get_name<1, sample>(); // Outputs: f_int f_long
//]
}
#endif
#if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
{
//[pfr_quick_examples_structure_to_tuple
// Getting a std::tuple of values from structures fields
struct foo { int a, b; };
struct other {
char c;
foo nested;
};
other var{'A', {3, 4}};
std::tuple<char, foo> t = boost::pfr::structure_to_tuple(var);
assert(std::get<0>(t) == 'A');
assert(
boost::pfr::eq(std::get<1>(t), foo{3, 4})
);
//]
}
#endif
#if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
{
//[pfr_quick_examples_structure_tie
// Getting a std::tuple of references to structure fields
struct foo { int a, b; };
struct other {
char c;
foo f;
};
other var{'A', {14, 15}};
std::tuple<char&, foo&> t = boost::pfr::structure_tie(var);
std::get<1>(t) = foo{1, 2};
std::cout << boost::pfr::io(var.f); // Outputs: {1, 2}
//]
}
#endif
} // void test_examples()
//[pfr_quick_examples_functions_for
// Define all the comparison and IO operators for my_structure type along
// with hash_value function.
#include <boost/pfr/functions_for.hpp>
namespace my_namespace {
struct my_structure {
int a,b,c,d,e,f,g;
// ...
};
BOOST_PFR_FUNCTIONS_FOR(my_structure)
}
//]
//[pfr_quick_examples_eq_fields
// Define only the equality and inequality operators for my_eq_ne_structure.
#include <boost/pfr/functions_for.hpp>
namespace my_namespace {
struct my_eq_ne_structure {
float a,b,c,d,e,f,g;
// ...
};
inline bool operator==(const my_eq_ne_structure& x, const my_eq_ne_structure& y) {
return boost::pfr::eq_fields(x, y);
}
inline bool operator!=(const my_eq_ne_structure& x, const my_eq_ne_structure& y) {
return boost::pfr::ne_fields(x, y);
}
}
//]
int main() {
test_examples();
}
|