1// Copyright 2020, 2021 Peter Dimov
2// Distributed under the Boost Software License, Version 1.0.
3// https://www.boost.org/LICENSE_1_0.txt
4
5#include <boost/describe/bases.hpp>
6#include <boost/describe/members.hpp>
7#include <boost/describe/class.hpp>
8#include <boost/core/lightweight_test.hpp>
9#include <boost/config.hpp>
10
11template<class A1, class A2> struct X
12{
13 A1 a1;
14 A2 a2;
15
16 BOOST_DESCRIBE_CLASS(X, (), (a1, a2), (), ())
17};
18
19template<class B1, class B2> class Y
20{
21private:
22
23 B1 b1;
24 B2 b2;
25
26 BOOST_DESCRIBE_CLASS(Y, (), (), (), (b1, b2))
27};
28
29template<class T1, class T2> class Z: public X<T1, T2>
30{
31private:
32
33 // error: declaration of 'typedef struct X<T1, T2> Z<T1, T2>::X' changes meaning of 'X' (g++)
34 // typedef X<T1, T2> X;
35
36 typedef X<T1, T2> XB;
37
38protected:
39
40 Y<T1, T2> y;
41
42 BOOST_DESCRIBE_CLASS(Z, (XB), (), (y), ())
43};
44
45#if !defined(BOOST_DESCRIBE_CXX14)
46
47#include <boost/config/pragma_message.hpp>
48
49BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available")
50int main() {}
51
52#elif defined(BOOST_MSVC) && BOOST_MSVC < 1920
53
54BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_MSVC is below 1920")
55int main() {}
56
57#elif defined(BOOST_MSVC) && BOOST_MSVC >= 1920 && BOOST_MSVC < 1940 && _MSVC_LANG <= 201703L
58
59BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_MSVC is 192x or 193x and _MSVC_LANG is 201703L or below")
60int main() {}
61
62#else
63
64#include <boost/mp11.hpp>
65using namespace boost::mp11;
66
67int main()
68{
69 using namespace boost::describe;
70 using namespace boost::mp11;
71
72 {
73 using L = describe_members<X<int, float>, mod_any_access>;
74
75 BOOST_TEST_EQ( mp_size<L>::value, 2 );
76
77 using D1 = mp_at_c<L, 0>;
78 using D2 = mp_at_c<L, 1>;
79
80 BOOST_TEST( D1::pointer == (&X<int, float>::a1) );
81 BOOST_TEST_CSTR_EQ( D1::name, "a1" );
82 BOOST_TEST_EQ( D1::modifiers, mod_public );
83
84 BOOST_TEST( D2::pointer == (&X<int, float>::a2) );
85 BOOST_TEST_CSTR_EQ( D2::name, "a2" );
86 BOOST_TEST_EQ( D2::modifiers, mod_public );
87 }
88
89 {
90 using L = describe_members<Y<int, float>, mod_any_access>;
91
92 BOOST_TEST_EQ( mp_size<L>::value, 2 );
93
94 using D1 = mp_at_c<L, 0>;
95 using D2 = mp_at_c<L, 1>;
96
97 // BOOST_TEST( D1::pointer == (&Y<int, float>::b1) );
98 BOOST_TEST_CSTR_EQ( D1::name, "b1" );
99 BOOST_TEST_EQ( D1::modifiers, mod_private );
100
101 // BOOST_TEST( D2::pointer == (&Y<int, float>::b2) );
102 BOOST_TEST_CSTR_EQ( D2::name, "b2" );
103 BOOST_TEST_EQ( D2::modifiers, mod_private );
104 }
105
106 {
107 using L = describe_members<Z<int, float>, mod_any_access>;
108
109 BOOST_TEST_EQ( mp_size<L>::value, 1 );
110
111 using D1 = mp_at_c<L, 0>;
112
113 // BOOST_TEST( D1::pointer == (&Z<int, float>::y) );
114 BOOST_TEST_CSTR_EQ( D1::name, "y" );
115 BOOST_TEST_EQ( D1::modifiers, mod_protected );
116 }
117
118 {
119 using L = describe_members<Z<int, float>, mod_any_access | mod_inherited>;
120
121 BOOST_TEST_EQ( mp_size<L>::value, 3 );
122
123 using D1 = mp_at_c<L, 0>;
124 using D2 = mp_at_c<L, 1>;
125 using D3 = mp_at_c<L, 2>;
126
127 BOOST_TEST( D1::pointer == (&X<int, float>::a1) );
128 BOOST_TEST_CSTR_EQ( D1::name, "a1" );
129 BOOST_TEST_EQ( D1::modifiers, mod_public | mod_inherited );
130
131 BOOST_TEST( D2::pointer == (&X<int, float>::a2) );
132 BOOST_TEST_CSTR_EQ( D2::name, "a2" );
133 BOOST_TEST_EQ( D2::modifiers, mod_public | mod_inherited );
134
135 // BOOST_TEST( D3::pointer == (&Z<int, float>::y) );
136 BOOST_TEST_CSTR_EQ( D3::name, "y" );
137 BOOST_TEST_EQ( D3::modifiers, mod_protected );
138 }
139
140 return boost::report_errors();
141}
142
143#endif // !defined(BOOST_DESCRIBE_CXX14)
144

source code of boost/libs/describe/test/class_template_test.cpp