]>
Commit | Line | Data |
---|---|---|
b74318f1 BW |
1 | // Test for Container using non-standard pointer types. |
2 | ||
99dee823 | 3 | // Copyright (C) 2008-2021 Free Software Foundation, Inc. |
b74318f1 BW |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
b74318f1 BW |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // You should have received a copy of the GNU General Public License along | |
748086b7 JJ |
17 | // with this library; see the file COPYING3. If not see |
18 | // <http://www.gnu.org/licenses/>. | |
b74318f1 | 19 | |
b74318f1 BW |
20 | |
21 | #include <algorithm> | |
22 | #include <testsuite_hooks.h> | |
23 | #include <ext/cast.h> | |
24 | #include <ext/pointer.h> | |
25 | ||
26 | using __gnu_cxx::_Pointer_adapter; | |
27 | using __gnu_cxx::_Relative_pointer_impl; | |
28 | using __gnu_cxx::__static_pointer_cast; | |
29 | using __gnu_cxx::__const_pointer_cast; | |
30 | ||
31 | ||
32 | void | |
33 | test01() { | |
b74318f1 BW |
34 | typedef _Pointer_adapter<_Relative_pointer_impl<int> > pointer; |
35 | typedef _Pointer_adapter<_Relative_pointer_impl<const int> > const_pointer; | |
36 | ||
37 | int A[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; | |
38 | ||
39 | // basic pointer assignment/access tests. | |
40 | pointer x = &A[0]; | |
41 | VERIFY(*x == 0); | |
42 | VERIFY(std::equal(x, x+10, A)); | |
43 | pointer y(&A[9]); | |
44 | VERIFY(*y == 9); | |
45 | ||
46 | // assignability | |
47 | pointer z(x); | |
48 | VERIFY(z==x); | |
49 | VERIFY(*z == 0); | |
50 | ||
51 | z = y; | |
52 | VERIFY(z==y); | |
53 | VERIFY(z!=x); | |
54 | VERIFY(z>x); | |
55 | VERIFY(*z == 9); | |
56 | ||
57 | // pointer arithmetic | |
58 | VERIFY(*++x == 1); | |
59 | VERIFY(*--x == 0); | |
60 | VERIFY(*(x++) == 0); | |
61 | VERIFY(*(x--) == 1); | |
62 | VERIFY(*(x+2) == 2); | |
63 | VERIFY(*(2+x) == 2); | |
64 | VERIFY(*(y-2) == 7); | |
65 | VERIFY(y - x == 9); | |
66 | VERIFY(&*y - x == 9); | |
67 | VERIFY(y - &*x == 9); | |
68 | ||
69 | size_t s(y - x); | |
70 | VERIFY(s == 9); | |
71 | } | |
72 | ||
73 | ||
74 | struct A { | |
75 | mutable int i; | |
76 | }; | |
77 | struct B : public A{ | |
78 | mutable int j; | |
79 | }; | |
80 | typedef _Pointer_adapter<_Relative_pointer_impl<B> > B_pointer; | |
81 | typedef _Pointer_adapter<_Relative_pointer_impl<A> > A_pointer; | |
82 | typedef _Pointer_adapter<_Relative_pointer_impl<const A> > const_A_pointer; | |
83 | typedef _Pointer_adapter<_Relative_pointer_impl<const B> > const_B_pointer; | |
84 | ||
85 | ||
86 | // Test implicit conversion from B* to A* | |
87 | void inc(_Pointer_adapter<_Relative_pointer_impl<A> > a) { | |
88 | a->i++; | |
89 | } | |
90 | // Test implicit conversion from B* to const B* | |
91 | void inc2(_Pointer_adapter<_Relative_pointer_impl<const B> > b) { | |
92 | b->i++; | |
93 | b->j++; | |
94 | } | |
95 | // Test implicit conversion from B* to const A* | |
96 | void inc3(_Pointer_adapter<_Relative_pointer_impl<const A> > a) { | |
97 | a->i++; | |
98 | } | |
99 | ||
100 | void test02() { | |
b74318f1 BW |
101 | B b; |
102 | b.i = 2; | |
103 | b.j = 2; | |
104 | ||
105 | B_pointer Bptr(&b); | |
106 | VERIFY(Bptr->i == 2); | |
107 | Bptr->i++; | |
108 | VERIFY(b.i == 3); | |
109 | ||
110 | const_B_pointer cBptr(&b); | |
111 | b.i++; | |
112 | VERIFY(cBptr->i == 4); | |
113 | ||
114 | A_pointer Aptr(&b); | |
115 | b.i++; | |
116 | VERIFY(Aptr->i == 5); | |
117 | Aptr->i++; | |
118 | VERIFY(b.i == 6); | |
119 | ||
120 | const_A_pointer cAptr(&b); | |
121 | b.i++; | |
122 | VERIFY(cAptr->i == 7); | |
123 | ||
124 | const_B_pointer cBptr2(Bptr); | |
125 | b.i++; | |
126 | VERIFY(cBptr2->i == 8); | |
127 | ||
128 | A_pointer Aptr2(Bptr); | |
129 | b.i++; | |
130 | VERIFY(Aptr2->i == 9); | |
131 | Aptr2->i++; | |
132 | VERIFY(b.i == 10); | |
133 | ||
134 | const_A_pointer cAptr2(Bptr); | |
135 | b.i++; | |
136 | VERIFY(cAptr2->i == 11); | |
137 | ||
138 | // Implicit casting during invocation | |
139 | inc(Bptr); | |
140 | VERIFY(Bptr->i == 12); | |
141 | inc2(Bptr); | |
142 | VERIFY(Bptr->i == 13); | |
143 | VERIFY(Bptr->j == 3); | |
144 | inc3(Bptr); | |
145 | VERIFY(Bptr->i == 14); | |
146 | } | |
147 | ||
148 | void test03() { | |
b74318f1 BW |
149 | B b; |
150 | B* bPtr = &b; | |
151 | A* aPtr __attribute__((unused)) = __static_pointer_cast<A*>(bPtr); | |
152 | const A *caPtr __attribute__((unused)) = __static_pointer_cast<const A*>(bPtr); | |
153 | const B *cbPtr __attribute__((unused)) = __static_pointer_cast<const B*>(bPtr); | |
154 | ||
155 | B_pointer Bptr2 = &b; | |
156 | ||
157 | const A* caPtr2 __attribute__((unused)) = __static_pointer_cast<const A*>(Bptr2); | |
158 | A * aPtr2 __attribute__((unused)) = __static_pointer_cast<A*>(Bptr2); | |
159 | const B* cbPtr2 __attribute__((unused)) = __const_pointer_cast<const B*>(Bptr2); | |
160 | ||
161 | const_A_pointer caPtr3 __attribute__((unused)) = __static_pointer_cast<const A*>(Bptr2); | |
162 | A_pointer aPtr3 __attribute__((unused)) = __static_pointer_cast<A*>(Bptr2); | |
163 | const_B_pointer cbPtr3 __attribute__((unused)) = __const_pointer_cast<const B*>(Bptr2); | |
164 | } | |
165 | ||
166 | // Confirm the usability of the __static_pointer_cast<> template function | |
167 | // to transform between _Pointer_adapter and standard versions. | |
168 | void test04() { | |
b74318f1 BW |
169 | B b; |
170 | B_pointer bPtr = &b; | |
171 | ||
172 | A_pointer aPtr = __static_pointer_cast<A_pointer>(bPtr); | |
173 | VERIFY(aPtr == bPtr); | |
174 | B_pointer bPtr2 = __static_pointer_cast<B_pointer>(aPtr); | |
175 | VERIFY(bPtr2 == aPtr); | |
176 | ||
177 | A* aPtr3 = __static_pointer_cast<A*>(bPtr); | |
178 | VERIFY(aPtr3 == bPtr); | |
179 | B* bPtr3 = __static_pointer_cast<B*>(aPtr); | |
180 | VERIFY(bPtr3 == aPtr); | |
181 | } | |
182 | ||
4a559e91 JW |
183 | // Check that long long values can be used for pointer arithmetic. |
184 | void test05() | |
185 | { | |
186 | A a[2] = { 1, 2 }; | |
187 | A_pointer p = a; | |
188 | A_pointer q = p + 0ull; | |
189 | VERIFY( p == q ); | |
190 | q += 0ll; | |
191 | VERIFY( p == q ); | |
192 | q += 1ll; | |
193 | VERIFY( q->i == p[1ll].i ); | |
194 | } | |
195 | ||
b74318f1 BW |
196 | int main() |
197 | { | |
198 | test01(); | |
199 | test02(); | |
200 | test03(); | |
201 | test04(); | |
4a559e91 | 202 | test05(); |
b74318f1 BW |
203 | return 0; |
204 | } |