1 // Copyright (c) 2020-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/core/lightweight_test.hpp>
7
8 #include <boost/pfr/core.hpp>
9
10 #include <string>
11 #include <type_traits>
12
13 #if defined(__has_include)
14 # if __has_include(<optional>) && (__cplusplus >= 201703L)
15 # include <optional>
16 # ifdef __cpp_lib_optional
17 # define BOOST_PFR_TEST_HAS_OPTIONAL 1
18 # endif
19 # endif
20 #endif
21
22 #ifndef BOOST_PFR_TEST_HAS_OPTIONAL
23 #define BOOST_PFR_TEST_HAS_OPTIONAL 0
24 #endif
25
26 namespace some {
27 struct struct1{ int i; };
28 struct struct2{ int i; };
29 }
30
31 namespace testing {
32
33 namespace {
34
35 #if BOOST_PFR_TEST_HAS_OPTIONAL
36 struct anon_with_optional {
37 std::string a;
38 std::optional<some::struct1> b;
39 std::optional<some::struct2> c;
40
41 };
42
43 struct other_anon_with_optional {
44 std::string a;
45 int b;
46 std::optional<anon_with_optional> c;
47 std::optional<some::struct2> d;
48
49 };
50 #endif
51
52 struct other_anon {
53 int data;
54 };
55
56 struct anon {
57 other_anon a;
58 const other_anon b;
59 };
60
test_in_anon_ns()61 void test_in_anon_ns() {
62 const anon const_x{{10}, {20}};
63
64 auto const_v = boost::pfr::structure_tie(const_x);
65 BOOST_TEST_EQ(std::get<0>(const_v).data, 10);
66 BOOST_TEST_EQ(std::get<1>(const_v).data, 20);
67 static_assert(std::is_same<
68 std::tuple<const other_anon&, const other_anon&>, decltype(const_v)
69 >::value, "");
70
71 // TODO: something is wrong with loophole and optional
72 #if BOOST_PFR_TEST_HAS_OPTIONAL && !BOOST_PFR_USE_LOOPHOLE
73 other_anon_with_optional opt{"test", {}, {}, {}};
74 auto opt_val = boost::pfr::structure_tie(opt);
75 BOOST_TEST_EQ(std::get<0>(opt_val), "test");
76 #endif
77 }
78
79 } // anonymous namespace
80
test_in_non_non_ns()81 void test_in_non_non_ns() {
82 const anon const_x{{10}, {20}};
83
84 auto const_v = boost::pfr::structure_tie(const_x);
85 BOOST_TEST_EQ(std::get<0>(const_v).data, 10);
86 BOOST_TEST_EQ(std::get<1>(const_v).data, 20);
87 static_assert(std::is_same<
88 std::tuple<const other_anon&, const other_anon&>, decltype(const_v)
89 >::value, "");
90
91 // TODO: something is wrong with loophole and optional
92 #if BOOST_PFR_TEST_HAS_OPTIONAL && !BOOST_PFR_USE_LOOPHOLE
93 other_anon_with_optional opt{"test again", {}, {}, {}};
94 auto opt_val = boost::pfr::structure_tie(opt);
95 BOOST_TEST_EQ(std::get<0>(opt_val), "test again");
96 #endif
97 }
98
99 } // namespace testing
100
main()101 int main() {
102 testing::test_in_anon_ns();
103 testing::test_in_non_non_ns();
104
105 return boost::report_errors();
106 }
107
108
109