1 // Copyright (c) 2016-2021 Antony Polukhin
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <boost/pfr/core.hpp>
7 #include <boost/core/lightweight_test.hpp>
8 #include <sstream>
9
10 // Test case was inspired by Bruno Dutra. Thanks!
11
12 enum class color {
13 red,
14 green,
15 blue
16 };
17
operator <<(std::ostream & os,color c)18 std::ostream& operator <<(std::ostream& os, color c) {
19 switch(c) {
20 case color::red:
21 os << "red";
22 break;
23 case color::green:
24 os << "green";
25 break;
26 case color::blue:
27 os << "blue";
28 break;
29 };
30
31 return os;
32 }
33
34
35 struct my_constexpr {
my_constexprmy_constexpr36 constexpr my_constexpr() {}
37 };
38
operator <<(std::ostream & os,my_constexpr)39 std::ostream& operator <<(std::ostream& os, my_constexpr) {
40 return os << "{}";
41 }
42
43 struct reg {
44 const int a;
45 char b;
46 const my_constexpr d;
47 const color f;
48 const char* g;
49 };
50
51 struct simple {
52 int a;
53 char b;
54 short d;
55 };
56
57
main()58 int main () {
59 std::size_t control = 0;
60
61 int v = {};
62 boost::pfr::for_each_field(v, [&control](auto&& val, std::size_t i) {
63 BOOST_TEST_EQ(i, control);
64 (void)val;
65 ++ control;
66 });
67 BOOST_TEST_EQ(control, 1);
68
69 control = 0;
70 int array[10] = {};
71 boost::pfr::for_each_field(array, [&control](auto&& val, std::size_t i) {
72 BOOST_TEST_EQ(i, control);
73 (void)val;
74 ++ control;
75 });
76 BOOST_TEST_EQ(control, 10);
77
78 std::stringstream ss;
79 boost::pfr::for_each_field(reg{42, 'a', {}, color::green, "hello world!"}, [&ss](auto&& val, std::size_t i) {
80 if (i) {
81 ss << ", ";
82 }
83 ss << val;
84 });
85 BOOST_TEST_EQ(std::string("42, a, {}, green, hello world!"), ss.str());
86 ss.str("");
87
88 control = 0;
89 boost::pfr::for_each_field(reg{42, 'a', {}, color::green, "hello world!"}, [&ss, &control](auto&& val, auto i) {
90 if (!!decltype(i)::value) {
91 ss << ", ";
92 }
93 BOOST_TEST_EQ(decltype(i)::value, control);
94 ++ control;
95 ss << val;
96 });
97 BOOST_TEST_EQ(std::string("42, a, {}, green, hello world!"), ss.str());
98 ss.str("");
99
100 boost::pfr::for_each_field(reg{42, 'a', {}, color::green, "hello world!"}, [&ss](auto&& val) {
101 ss << val << ' ';
102 });
103 BOOST_TEST_EQ(std::string("42 a {} green hello world! "), ss.str());
104 ss.str("");
105
106 std::cout << '\n';
107 boost::pfr::for_each_field(simple{42, 'a', 3}, [&ss](auto&& val) {
108 ss << val << ' ';
109 });
110 BOOST_TEST_EQ("42 a 3 ", ss.str());
111
112 return boost::report_errors();
113 }
114