1 
2 #include "catch.hpp"
3 
4 #include <mapbox/recursive_wrapper.hpp>
5 
6 #include <type_traits>
7 #include <utility>
8 
9 using rwi = mapbox::util::recursive_wrapper<int>;
10 using rwp = mapbox::util::recursive_wrapper<std::pair<int, int>>;
11 
12 static_assert(std::is_same<rwi::type, int>::value, "type check failed");
13 
14 TEST_CASE("recursive wrapper of int")
15 {
16 
17     SECTION("construct with value")
18     {
19         rwi a{7};
20 
21         REQUIRE(a.get() == 7);
22         REQUIRE(*a.get_pointer() == 7);
23 
24         a = 8;
25         REQUIRE(a.get() == 8);
26 
27         rwi b{a};
28         REQUIRE(b.get() == 8);
29 
30         rwi c;
31         c = b;
32         REQUIRE(b.get() == 8);
33         REQUIRE(c.get() == 8);
34 
35         c = 9;
36         REQUIRE(c.get() == 9);
37 
38         int x = 10;
39         c = x;
40         REQUIRE(c.get() == 10);
41 
42         b = std::move(c);
43         REQUIRE(b.get() == 10);
44     }
45 
46     SECTION("construct with const reference")
47     {
48         int i = 7;
49         rwi a{i};
50 
51         REQUIRE(a.get() == 7);
52     }
53 
54     SECTION("implicit conversion to reference of underlying type")
55     {
56 
57         SECTION("const")
58         {
59             rwi const a{7};
60             REQUIRE(a.get() == 7);
61             REQUIRE(*a.get_pointer() == 7);
62 
63             rwi::type const& underlying = a;
64             REQUIRE(underlying == 7);
65         }
66 
67         SECTION("non const")
68         {
69             rwi a{7};
70             REQUIRE(a.get() == 7);
71             REQUIRE(*a.get_pointer() == 7);
72 
73             rwi::type& underlying = a;
74             REQUIRE(underlying == 7);
75             a = 8;
76             REQUIRE(underlying == 8);
77         }
78     }
79 }
80 
81 TEST_CASE("move of recursive wrapper")
82 {
83     rwi a{1};
84 
85     SECTION("move constructor")
86     {
87         rwi b{std::move(a)};
88         REQUIRE(b.get() == 1);
89     }
90 
91     SECTION("operator= on rvalue")
92     {
93         rwi b{2};
94         b = std::move(a);
95         REQUIRE(b.get() == 1);
96     }
97 }
98 
99 TEST_CASE("swap")
100 {
101     rwi a{1};
102     rwi b{2};
103 
104     REQUIRE(a.get() == 1);
105     REQUIRE(b.get() == 2);
106 
107     using std::swap;
108     swap(a, b);
109 
110     REQUIRE(a.get() == 2);
111     REQUIRE(b.get() == 1);
112 }
113 
114 TEST_CASE("recursive wrapper of pair<int, int>")
115 {
116 
117     SECTION("default constructed")
118     {
119         rwp a;
120         REQUIRE(a.get().first == 0);
121         REQUIRE(a.get().second == 0);
122     }
123 
124     SECTION("construct with value")
125     {
126         rwp a{std::make_pair(1, 2)};
127 
128         REQUIRE(a.get().first == 1);
129         REQUIRE(a.get().second == 2);
130 
131         REQUIRE(a.get_pointer()->first == 1);
132         REQUIRE(a.get_pointer()->second == 2);
133 
134         a = {3, 4};
135         REQUIRE(a.get().first == 3);
136         REQUIRE(a.get().second == 4);
137 
138         rwp b{a};
139         REQUIRE(b.get().first == 3);
140         REQUIRE(b.get().second == 4);
141 
142         rwp c;
143         c = b;
144         REQUIRE(b.get().first == 3);
145         REQUIRE(b.get().second == 4);
146         REQUIRE(c.get().first == 3);
147         REQUIRE(c.get().second == 4);
148 
149         c = {5, 6};
150         REQUIRE(c.get().first == 5);
151         REQUIRE(c.get().second == 6);
152 
153         b = std::move(c);
154         REQUIRE(b.get().first == 5);
155         REQUIRE(b.get().second == 6);
156         //        REQUIRE(c.get_pointer() == nullptr);
157     }
158 }
159