1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2007-2012. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/interprocess for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#include <boost/interprocess/offset_ptr.hpp>
12#include <boost/interprocess/detail/type_traits.hpp>
13#include <boost/intrusive/pointer_traits.hpp>
14#include <boost/static_assert.hpp>
15#include <boost/core/lightweight_test.hpp>
16
17using namespace boost::interprocess;
18
19class Base
20{};
21
22class Derived
23 : public Base
24{};
25
26class VirtualDerived
27 : public virtual Base
28{};
29
30void test_types_and_conversions()
31{
32 typedef offset_ptr<int> pint_t;
33 typedef offset_ptr<const int> pcint_t;
34 typedef offset_ptr<volatile int> pvint_t;
35 typedef offset_ptr<const volatile int> pcvint_t;
36
37 BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::element_type, int>::value));
38 BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::element_type, const int>::value));
39 BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::element_type, volatile int>::value));
40 BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::element_type, const volatile int>::value));
41
42 BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::value_type, int>::value));
43 BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::value_type, int>::value));
44 BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::value_type, int>::value));
45 BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::value_type, int>::value));
46 int dummy_int = 9;
47
48 { pint_t pint(&dummy_int);
49 pcint_t pcint(pint);
50 BOOST_TEST(pcint.get() == &dummy_int);
51 }
52 { pint_t pint(&dummy_int);
53 pvint_t pvint(pint);
54 BOOST_TEST(pvint.get() == &dummy_int);
55 }
56 { pint_t pint(&dummy_int);
57 pcvint_t pcvint(pint);
58 BOOST_TEST(pcvint.get() == &dummy_int);
59 }
60 { pcint_t pcint(&dummy_int);
61 pcvint_t pcvint(pcint);
62 BOOST_TEST(pcvint.get() == &dummy_int);
63 }
64 { pvint_t pvint(&dummy_int);
65 pcvint_t pcvint(pvint);
66 BOOST_TEST(pcvint.get() == &dummy_int);
67 }
68
69 pint_t pint(0);
70 pcint_t pcint(0);
71 pvint_t pvint(0);
72 pcvint_t pcvint(0);
73
74 pint = &dummy_int;
75 pcint = &dummy_int;
76 pvint = &dummy_int;
77 pcvint = &dummy_int;
78
79 { pcint = pint;
80 BOOST_TEST(pcint.get() == &dummy_int);
81 }
82 { pvint = pint;
83 BOOST_TEST(pvint.get() == &dummy_int);
84 }
85 { pcvint = pint;
86 BOOST_TEST(pcvint.get() == &dummy_int);
87 }
88 { pcvint = pcint;
89 BOOST_TEST(pcvint.get() == &dummy_int);
90 }
91 { pcvint = pvint;
92 BOOST_TEST(pcvint.get() == &dummy_int);
93 }
94
95 BOOST_TEST(pint);
96
97 pint = 0;
98 BOOST_TEST(!pint);
99
100 BOOST_TEST(pint == 0);
101
102 BOOST_TEST(0 == pint);
103
104 pint = &dummy_int;
105 BOOST_TEST(0 != pint);
106
107 pcint = &dummy_int;
108
109 BOOST_TEST( (pcint - pint) == 0);
110 BOOST_TEST( (pint - pcint) == 0);
111}
112
113template<class BasePtr, class DerivedPtr>
114void test_base_derived_impl()
115{
116 typename DerivedPtr::element_type d;
117 DerivedPtr pderi(&d);
118
119 BasePtr pbase(pderi);
120 pbase = pderi;
121 BOOST_TEST(pbase == pderi);
122 BOOST_TEST(!(pbase != pderi));
123 BOOST_TEST((pbase - pderi) == 0);
124 BOOST_TEST(!(pbase < pderi));
125 BOOST_TEST(!(pbase > pderi));
126 BOOST_TEST(pbase <= pderi);
127 BOOST_TEST((pbase >= pderi));
128}
129
130void test_base_derived()
131{
132 typedef offset_ptr<Base> pbase_t;
133 typedef offset_ptr<const Base> pcbas_t;
134 typedef offset_ptr<Derived> pderi_t;
135 typedef offset_ptr<VirtualDerived> pvder_t;
136
137 test_base_derived_impl<pbase_t, pderi_t>();
138 test_base_derived_impl<pbase_t, pvder_t>();
139 test_base_derived_impl<pcbas_t, pderi_t>();
140 test_base_derived_impl<pcbas_t, pvder_t>();
141}
142
143void test_arithmetic()
144{
145 typedef offset_ptr<int> pint_t;
146 const int NumValues = 5;
147 int values[NumValues];
148
149 //Initialize p
150 pint_t p = values;
151 BOOST_TEST(p.get() == values);
152
153 //Initialize p + NumValues
154 pint_t pe = &values[NumValues];
155 BOOST_TEST(pe != p);
156 BOOST_TEST(pe.get() == &values[NumValues]);
157
158 //ptr - ptr
159 BOOST_TEST((pe - p) == NumValues);
160
161 //ptr - integer
162 BOOST_TEST((pe - NumValues) == p);
163
164 //ptr + integer
165 BOOST_TEST((p + NumValues) == pe);
166
167 //integer + ptr
168 BOOST_TEST((NumValues + p) == pe);
169
170 //indexing
171 BOOST_TEST(pint_t(&p[NumValues]) == pe);
172 BOOST_TEST(pint_t(&pe[-NumValues]) == p);
173
174 //ptr -= integer
175 pint_t p0 = pe;
176 p0-= NumValues;
177 BOOST_TEST(p == p0);
178
179 //ptr += integer
180 pint_t penew = p0;
181 penew += NumValues;
182 BOOST_TEST(penew == pe);
183
184 //++ptr
185 penew = p0;
186 for(int j = 0; j != NumValues; ++j, ++penew);
187 BOOST_TEST(penew == pe);
188
189 //--ptr
190 p0 = pe;
191 for(int j = 0; j != NumValues; ++j, --p0);
192 BOOST_TEST(p == p0);
193
194 //ptr++
195 penew = p0;
196 for(int j = 0; j != NumValues; ++j){
197 pint_t p_new_copy = penew;
198 BOOST_TEST(p_new_copy == penew++);
199 }
200 //ptr--
201 p0 = pe;
202 for(int j = 0; j != NumValues; ++j){
203 pint_t p0_copy = p0;
204 BOOST_TEST(p0_copy == p0--);
205 }
206}
207
208void test_comparison()
209{
210 typedef offset_ptr<int> pint_t;
211 const int NumValues = 5;
212 int values[NumValues];
213
214 //Initialize p
215 pint_t p = values;
216 BOOST_TEST(p.get() == values);
217
218 //Initialize p + NumValues
219 pint_t pe = &values[NumValues];
220 BOOST_TEST(pe != p);
221
222 BOOST_TEST(pe.get() == &values[NumValues]);
223
224 //operators
225 BOOST_TEST(p != pe);
226 BOOST_TEST(p == p);
227 BOOST_TEST((p < pe));
228 BOOST_TEST((p <= pe));
229 BOOST_TEST((pe > p));
230 BOOST_TEST((pe >= p));
231}
232
233bool test_pointer_traits()
234{
235 typedef offset_ptr<int> OInt;
236 typedef boost::intrusive::pointer_traits< OInt > PTOInt;
237 BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::element_type, int>::value));
238 BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::pointer, OInt >::value));
239 BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::difference_type, OInt::difference_type >::value));
240 BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::rebind_pointer<double>::type, offset_ptr<double> >::value));
241 int dummy;
242 OInt oi(&dummy);
243 if(boost::intrusive::pointer_traits<OInt>::pointer_to(r&: dummy) != oi){
244 return false;
245 }
246 return true;
247}
248
249struct node
250{
251 offset_ptr<node> next;
252};
253
254void test_pointer_plus_bits()
255{
256 BOOST_STATIC_ASSERT((boost::intrusive::max_pointer_plus_bits< offset_ptr<void>, boost::move_detail::alignment_of<node>::value >::value >= 1U));
257 typedef boost::intrusive::pointer_plus_bits< offset_ptr<node>, 1u > ptr_plus_bits;
258
259 node n, n2;
260 offset_ptr<node> pnode(&n);
261
262 BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
263 BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
264 ptr_plus_bits::set_bits(n&: pnode, b: 1u);
265 BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
266 BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
267
268 ptr_plus_bits::set_pointer(n&: pnode, p: &n2);
269 BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
270 BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
271 ptr_plus_bits::set_bits(n&: pnode, b: 0u);
272 BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
273 BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
274
275 ptr_plus_bits::set_pointer(n&: pnode, p: offset_ptr<node>());
276 BOOST_TEST(ptr_plus_bits::get_pointer(pnode) ==0);
277 BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
278 ptr_plus_bits::set_bits(n&: pnode, b: 1u);
279 BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
280 BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == 0);
281}
282
283int main()
284{
285 test_types_and_conversions();
286 test_base_derived();
287 test_arithmetic();
288 test_comparison();
289 test_pointer_traits();
290 test_pointer_plus_bits();
291 return ::boost::report_errors();
292}
293

source code of boost/libs/interprocess/test/offset_ptr_test.cpp