1 /***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht          *
3 * Copyright (c) QuantStack                                                 *
4 *                                                                          *
5 * Distributed under the terms of the BSD 3-Clause License.                 *
6 *                                                                          *
7 * The full license is in the file LICENSE, distributed with this software. *
8 ****************************************************************************/
9 
10 #include "xtl/xvisitor.hpp"
11 
12 #include "test_common_macros.hpp"
13 
14 namespace xtl
15 {
16     class root : public base_visitable<int, false>
17     {
18     public:
19 
20         XTL_DEFINE_VISITABLE()
21     };
22 
23     class leaf_one : public root
24     {
25     public:
26 
27         XTL_DEFINE_VISITABLE()
28     };
29 
30     class leaf_two : public root
31     {
32     public:
33 
34         XTL_DEFINE_VISITABLE()
35     };
36 
37     class acyclic_visitor_tester
38         : public base_visitor
39         , public visitor<mpl::vector<leaf_one, leaf_two>, int, false>
40     {
41     public:
42 
visit(leaf_one &)43         int visit(leaf_one&) override
44         {
45             return 1;
46         }
47 
visit(leaf_two &)48         int visit(leaf_two&) override
49         {
50             return 2;
51         }
52     };
53 
TEST(visitor,acyclic_visitor)54     TEST(visitor, acyclic_visitor)
55     {
56         leaf_one l1;
57         leaf_two l2;
58         root* r1 = &l1;
59         root* r2 = &l2;
60 
61         acyclic_visitor_tester t;
62 
63         int res1 = r1->accept(t);
64         EXPECT_EQ(res1, 1);
65 
66         int res2 = r2->accept(t);
67         EXPECT_EQ(res2, 2);
68     }
69 
70     class const_root : public base_visitable<int, true>
71     {
72     public:
73 
74         XTL_DEFINE_CONST_VISITABLE()
75     };
76 
77     class const_leaf_one : public const_root
78     {
79     public:
80 
81         XTL_DEFINE_CONST_VISITABLE()
82     };
83 
84     class const_leaf_two : public const_root
85     {
86     public:
87 
88         XTL_DEFINE_CONST_VISITABLE()
89     };
90 
91     class const_acyclic_visitor_tester
92         : public base_visitor
93         , public visitor<mpl::vector<const_leaf_one, const_leaf_two>, int, true>
94     {
95     public:
96 
visit(const const_leaf_one &)97         int visit(const const_leaf_one&) override
98         {
99             return 1;
100         }
101 
visit(const const_leaf_two &)102         int visit(const const_leaf_two&) override
103         {
104             return 2;
105         }
106     };
107 
TEST(visitor,const_acyclic_visitor)108     TEST(visitor, const_acyclic_visitor)
109     {
110         const_leaf_one l1;
111         const_leaf_two l2;
112         const_root* r1 = &l1;
113         const_root* r2 = &l2;
114 
115         const_acyclic_visitor_tester t;
116 
117         int res1 = r1->accept(t);
118         EXPECT_EQ(res1, 1);
119 
120         int res2 = r2->accept(t);
121         EXPECT_EQ(res2, 2);
122     }
123 
124     class cleaf_one;
125     class cleaf_two;
126 
127     class cyclic_visitor_tester
128         : public cyclic_visitor<mpl::vector<cleaf_one, cleaf_two>, int, false>
129     {
130     public:
131 
visit(cleaf_one &)132         int visit(cleaf_one&) override
133         {
134             return 1;
135         }
136 
visit(cleaf_two &)137         int visit(cleaf_two&) override
138         {
139             return 2;
140         }
141     };
142 
143     class croot
144     {
145     public:
146 
147         virtual int accept(cyclic_visitor_tester&) = 0;
148     };
149 
150     class cleaf_one : public croot
151     {
152     public:
153 
154         XTL_DEFINE_CYCLIC_VISITABLE(cyclic_visitor_tester)
155     };
156 
157     class cleaf_two : public croot
158     {
159     public:
160 
161         XTL_DEFINE_CYCLIC_VISITABLE(cyclic_visitor_tester)
162     };
163 
TEST(visitor,cyclic_visitor)164     TEST(visitor, cyclic_visitor)
165     {
166         cleaf_one l1;
167         cleaf_two l2;
168         croot* r1 = &l1;
169         croot* r2 = &l2;
170 
171         cyclic_visitor_tester t;
172 
173         int res1 = r1->accept(t);
174         EXPECT_EQ(res1, 1);
175 
176         int res2 = r2->accept(t);
177         EXPECT_EQ(res2, 2);
178     }
179 
180     class ccleaf_one;
181     class ccleaf_two;
182 
183     class ccyclic_visitor_tester
184         : public cyclic_visitor<mpl::vector<ccleaf_one, ccleaf_two>, int, true>
185     {
186     public:
187 
visit(const ccleaf_one &)188         int visit(const ccleaf_one&) override
189         {
190             return 1;
191         }
192 
visit(const ccleaf_two &)193         int visit(const ccleaf_two&) override
194         {
195             return 2;
196         }
197     };
198 
199     class ccroot
200     {
201     public:
202 
203         virtual int accept(ccyclic_visitor_tester&) const = 0;
204     };
205 
206     class ccleaf_one : public ccroot
207     {
208     public:
209 
210         XTL_DEFINE_CONST_CYCLIC_VISITABLE(ccyclic_visitor_tester)
211     };
212 
213     class ccleaf_two : public ccroot
214     {
215     public:
216 
217         XTL_DEFINE_CONST_CYCLIC_VISITABLE(ccyclic_visitor_tester)
218     };
219 
TEST(visitor,const_cyclic_visitor)220     TEST(visitor, const_cyclic_visitor)
221     {
222         ccleaf_one l1;
223         ccleaf_two l2;
224         ccroot* r1 = &l1;
225         ccroot* r2 = &l2;
226 
227         ccyclic_visitor_tester t;
228 
229         int res1 = r1->accept(t);
230         EXPECT_EQ(res1, 1);
231 
232         int res2 = r2->accept(t);
233         EXPECT_EQ(res2, 2);
234     }
235 }
236 
237