Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / interprocess / test / offset_ptr_test.cpp
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/detail/config_begin.hpp>
12 #include <boost/interprocess/offset_ptr.hpp>
13 #include <boost/interprocess/detail/type_traits.hpp>
14 #include <boost/intrusive/pointer_traits.hpp>
15 #include <boost/static_assert.hpp>
16
17 using namespace boost::interprocess;
18
19 class Base
20 {};
21
22 class Derived
23    : public Base
24 {};
25
26 class VirtualDerived
27    : public virtual Base
28 {};
29
30 bool 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);   pcint_t  pcint(pint);
49       if(pcint.get()  != &dummy_int)   return false;  }
50    {  pint_t pint(&dummy_int);   pvint_t  pvint(pint);
51       if(pvint.get()  != &dummy_int)   return false;  }
52    {  pint_t pint(&dummy_int);   pcvint_t  pcvint(pint);
53       if(pcvint.get()  != &dummy_int)  return false;  }
54    {  pcint_t pcint(&dummy_int); pcvint_t  pcvint(pcint);
55          if(pcvint.get()  != &dummy_int)  return false;  }
56    {  pvint_t pvint(&dummy_int); pcvint_t  pcvint(pvint);
57       if(pcvint.get()  != &dummy_int)  return false;  }
58
59    pint_t   pint(0);
60    pcint_t  pcint(0);
61    pvint_t  pvint(0);
62    pcvint_t pcvint(0);
63
64    pint     = &dummy_int;
65    pcint    = &dummy_int;
66    pvint    = &dummy_int;
67    pcvint   = &dummy_int;
68
69    {   pcint  = pint;   if(pcint.get() != &dummy_int)   return false;  }
70    {   pvint  = pint;   if(pvint.get() != &dummy_int)   return false;  }
71    {   pcvint = pint;   if(pcvint.get() != &dummy_int)  return false;  }
72    {   pcvint = pcint;  if(pcvint.get() != &dummy_int)  return false;  }
73    {   pcvint = pvint;  if(pcvint.get() != &dummy_int)  return false;  }
74
75    if(!pint)
76       return false;
77
78    pint = 0;
79    if(pint)
80       return false;
81
82    if(pint != 0)
83       return false;
84
85    if(0 != pint)
86       return false;
87
88    pint = &dummy_int;
89    if(0 == pint)
90       return false;
91
92    if(pint == 0)
93       return false;
94
95    pcint = &dummy_int;
96
97    if( (pcint - pint) != 0)
98       return false;
99
100    if( (pint - pcint) != 0)
101       return false;
102
103    return true;
104 }
105
106 template<class BasePtr, class DerivedPtr>
107 bool test_base_derived_impl()
108 {
109    typename DerivedPtr::element_type d;
110    DerivedPtr pderi(&d);
111
112    BasePtr pbase(pderi);
113    pbase = pderi;
114    if(pbase != pderi)
115       return false;
116    if(!(pbase == pderi))
117       return false;
118    if((pbase - pderi) != 0)
119       return false;
120    if(pbase < pderi)
121       return false;
122    if(pbase > pderi)
123       return false;
124    if(!(pbase <= pderi))
125       return false;
126    if(!(pbase >= pderi))
127       return false;
128
129    return true;
130 }
131
132 bool test_base_derived()
133 {
134    typedef offset_ptr<Base>               pbase_t;
135    typedef offset_ptr<const Base>         pcbas_t;
136    typedef offset_ptr<Derived>            pderi_t;
137    typedef offset_ptr<VirtualDerived>     pvder_t;
138
139    if(!test_base_derived_impl<pbase_t, pderi_t>())
140       return false;
141    if(!test_base_derived_impl<pbase_t, pvder_t>())
142       return false;
143    if(!test_base_derived_impl<pcbas_t, pderi_t>())
144       return false;
145    if(!test_base_derived_impl<pcbas_t, pvder_t>())
146       return false;
147
148    return true;
149 }
150
151 bool test_arithmetic()
152 {
153    typedef offset_ptr<int> pint_t;
154    const int NumValues = 5;
155    int values[NumValues];
156
157    //Initialize p
158    pint_t p = values;
159    if(p.get() != values)
160       return false;
161
162    //Initialize p + NumValues
163    pint_t pe = &values[NumValues];
164    if(pe == p)
165       return false;
166    if(pe.get() != &values[NumValues])
167       return false;
168
169    //ptr - ptr
170    if((pe - p) != NumValues)
171       return false;
172    //ptr - integer
173    if((pe - NumValues) != p)
174       return false;
175    //ptr + integer
176    if((p + NumValues) != pe)
177       return false;
178    //integer + ptr
179    if((NumValues + p) != pe)
180       return false;
181    //indexing
182    if(pint_t(&p[NumValues])   != pe)
183       return false;
184    if(pint_t(&pe[-NumValues]) != p)
185       return false;
186
187    //ptr -= integer
188    pint_t p0 = pe;
189    p0-= NumValues;
190    if(p != p0)
191       return false;
192    //ptr += integer
193    pint_t penew = p0;
194    penew += NumValues;
195    if(penew != pe)
196       return false;
197
198    //++ptr
199    penew = p0;
200    for(int j = 0; j != NumValues; ++j, ++penew);
201    if(penew != pe)
202       return false;
203    //--ptr
204    p0 = pe;
205    for(int j = 0; j != NumValues; ++j, --p0);
206    if(p != p0)
207       return false;
208    //ptr++
209    penew = p0;
210    for(int j = 0; j != NumValues; ++j){
211       pint_t p_new_copy = penew;
212       if(p_new_copy != penew++)
213          return false;
214    }
215    //ptr--
216    p0 = pe;
217    for(int j = 0; j != NumValues; ++j){
218       pint_t p0_copy = p0;
219       if(p0_copy != p0--)
220          return false;
221    }
222
223    return true;
224 }
225
226 bool test_comparison()
227 {
228    typedef offset_ptr<int> pint_t;
229    const int NumValues = 5;
230    int values[NumValues];
231
232    //Initialize p
233    pint_t p = values;
234    if(p.get() != values)
235       return false;
236
237    //Initialize p + NumValues
238    pint_t pe = &values[NumValues];
239    if(pe == p)
240       return false;
241    if(pe.get() != &values[NumValues])
242       return false;
243
244    //operators
245    if(p == pe)
246       return false;
247    if(p != p)
248       return false;
249    if(!(p < pe))
250       return false;
251    if(!(p <= pe))
252       return false;
253    if(!(pe > p))
254       return false;
255    if(!(pe >= p))
256       return false;
257
258    return true;
259 }
260
261 bool test_pointer_traits()
262 {
263    typedef offset_ptr<int> OInt;
264    typedef boost::intrusive::pointer_traits< OInt > PTOInt;
265    BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::element_type, int>::value));
266    BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::pointer, OInt >::value));
267    BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::difference_type, OInt::difference_type >::value));
268    BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::rebind_pointer<double>::type, offset_ptr<double> >::value));
269    int dummy;
270    OInt oi(&dummy);
271    if(boost::intrusive::pointer_traits<OInt>::pointer_to(dummy) != oi){
272       return false;
273    }
274    return true;
275 }
276
277 int main()
278 {
279    if(!test_types_and_conversions())
280       return 1;
281    if(!test_base_derived())
282       return 1;
283    if(!test_arithmetic())
284       return 1;
285    if(!test_comparison())
286       return 1;
287    if(!test_pointer_traits())
288       return 1;
289    return 0;
290 }
291
292 #include <boost/interprocess/detail/config_end.hpp>
293
294 /*
295 //Offset ptr benchmark
296 #include <vector>
297 #include <iostream>
298 #include <boost/interprocess/managed_shared_memory.hpp>
299 #include <boost/interprocess/containers/vector.hpp>
300 #include <boost/interprocess/allocators/allocator.hpp>
301 #include <boost/timer.hpp>
302 #include <cstddef>
303
304 template<class InIt,
305    class Ty> inline
306    Ty accumulate2(InIt First, InIt Last, Ty Val)
307    {   // return sum of Val and all in [First, Last)
308    for (; First != Last; ++First) //First = First + 1)
309       Val = Val + *First;
310    return (Val);
311    }
312
313 template <typename Vector>
314 void time_test(const Vector& vec, std::size_t iterations, const char* label) {
315   // assert(!vec.empty())
316   boost::timer t;
317   typename Vector::const_iterator first = vec.begin();
318   typename Vector::value_type result(0);
319   while (iterations != 0) {
320     result = accumulate2(first, first + vec.size(), result);
321     --iterations;
322   }
323   std::cout << label << t.elapsed() << " " << result << std::endl;
324 }
325
326 int main()
327 {
328    using namespace boost::interprocess;
329    typedef allocator<double, managed_shared_memory::segment_manager> alloc_t;
330
331    std::size_t n = 0x1 << 26;
332    std::size_t file_size = n * sizeof(double) + 1000000;
333
334    {
335       shared_memory_object::remove("MyMappedFile");
336       managed_shared_memory segment(open_or_create, "MyMappedFile", file_size);
337       shared_memory_object::remove("MyMappedFile");
338       alloc_t alloc_inst(segment.get_segment_manager());
339       vector<double, alloc_t>  v0(n, double(42.42), alloc_inst);
340       time_test(v0, 10, "iterator   shared:     ");
341    }
342    {
343       std::vector<double>      v1(n, double(42.42));
344       time_test(v1, 10, "iterator   non-shared: ");
345    }
346   return 0;
347 }
348
349 */