• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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