1 // Test for Container using non-standard pointer types.
2 
3 // Copyright (C) 2008-2020 Free Software Foundation, Inc.
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
8 // Free Software Foundation; either version 3, or (at your option)
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
17 // with this library; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
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
test01()33 test01() {
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*
inc(_Pointer_adapter<_Relative_pointer_impl<A>> a)87 void inc(_Pointer_adapter<_Relative_pointer_impl<A> > a) {
88   a->i++;
89 }
90 // Test implicit conversion from B* to const B*
inc2(_Pointer_adapter<_Relative_pointer_impl<const B>> 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*
inc3(_Pointer_adapter<_Relative_pointer_impl<const A>> a)96 void inc3(_Pointer_adapter<_Relative_pointer_impl<const A> > a) {
97   a->i++;
98 }
99 
test02()100 void test02() {
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 
test03()148 void test03() {
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.
test04()168 void test04() {
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 
183 // Check that long long values can be used for pointer arithmetic.
test05()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 
main()196 int main()
197 {
198   test01();
199   test02();
200   test03();
201   test04();
202   test05();
203   return 0;
204 }
205