123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2007-2012. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // See http://www.boost.org/libs/interprocess for documentation.
- //
- //////////////////////////////////////////////////////////////////////////////
- #include <boost/interprocess/detail/config_begin.hpp>
- #include <boost/interprocess/offset_ptr.hpp>
- #include <boost/interprocess/detail/type_traits.hpp>
- #include <boost/intrusive/pointer_traits.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/core/lightweight_test.hpp>
- using namespace boost::interprocess;
- class Base
- {};
- class Derived
- : public Base
- {};
- class VirtualDerived
- : public virtual Base
- {};
- void test_types_and_conversions()
- {
- typedef offset_ptr<int> pint_t;
- typedef offset_ptr<const int> pcint_t;
- typedef offset_ptr<volatile int> pvint_t;
- typedef offset_ptr<const volatile int> pcvint_t;
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::element_type, int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::element_type, const int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::element_type, volatile int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::element_type, const volatile int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::value_type, int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::value_type, int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::value_type, int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::value_type, int>::value));
- int dummy_int = 9;
- { pint_t pint(&dummy_int);
- pcint_t pcint(pint);
- BOOST_TEST(pcint.get() == &dummy_int);
- }
- { pint_t pint(&dummy_int);
- pvint_t pvint(pint);
- BOOST_TEST(pvint.get() == &dummy_int);
- }
- { pint_t pint(&dummy_int);
- pcvint_t pcvint(pint);
- BOOST_TEST(pcvint.get() == &dummy_int);
- }
- { pcint_t pcint(&dummy_int);
- pcvint_t pcvint(pcint);
- BOOST_TEST(pcvint.get() == &dummy_int);
- }
- { pvint_t pvint(&dummy_int);
- pcvint_t pcvint(pvint);
- BOOST_TEST(pcvint.get() == &dummy_int);
- }
- pint_t pint(0);
- pcint_t pcint(0);
- pvint_t pvint(0);
- pcvint_t pcvint(0);
- pint = &dummy_int;
- pcint = &dummy_int;
- pvint = &dummy_int;
- pcvint = &dummy_int;
- { pcint = pint;
- BOOST_TEST(pcint.get() == &dummy_int);
- }
- { pvint = pint;
- BOOST_TEST(pvint.get() == &dummy_int);
- }
- { pcvint = pint;
- BOOST_TEST(pcvint.get() == &dummy_int);
- }
- { pcvint = pcint;
- BOOST_TEST(pcvint.get() == &dummy_int);
- }
- { pcvint = pvint;
- BOOST_TEST(pcvint.get() == &dummy_int);
- }
- BOOST_TEST(pint);
- pint = 0;
- BOOST_TEST(!pint);
- BOOST_TEST(pint == 0);
- BOOST_TEST(0 == pint);
- pint = &dummy_int;
- BOOST_TEST(0 != pint);
- pcint = &dummy_int;
- BOOST_TEST( (pcint - pint) == 0);
- BOOST_TEST( (pint - pcint) == 0);
- }
- template<class BasePtr, class DerivedPtr>
- void test_base_derived_impl()
- {
- typename DerivedPtr::element_type d;
- DerivedPtr pderi(&d);
- BasePtr pbase(pderi);
- pbase = pderi;
- BOOST_TEST(pbase == pderi);
- BOOST_TEST(!(pbase != pderi));
- BOOST_TEST((pbase - pderi) == 0);
- BOOST_TEST(!(pbase < pderi));
- BOOST_TEST(!(pbase > pderi));
- BOOST_TEST(pbase <= pderi);
- BOOST_TEST((pbase >= pderi));
- }
- void test_base_derived()
- {
- typedef offset_ptr<Base> pbase_t;
- typedef offset_ptr<const Base> pcbas_t;
- typedef offset_ptr<Derived> pderi_t;
- typedef offset_ptr<VirtualDerived> pvder_t;
- test_base_derived_impl<pbase_t, pderi_t>();
- test_base_derived_impl<pbase_t, pvder_t>();
- test_base_derived_impl<pcbas_t, pderi_t>();
- test_base_derived_impl<pcbas_t, pvder_t>();
- }
- void test_arithmetic()
- {
- typedef offset_ptr<int> pint_t;
- const int NumValues = 5;
- int values[NumValues];
- //Initialize p
- pint_t p = values;
- BOOST_TEST(p.get() == values);
- //Initialize p + NumValues
- pint_t pe = &values[NumValues];
- BOOST_TEST(pe != p);
- BOOST_TEST(pe.get() == &values[NumValues]);
- //ptr - ptr
- BOOST_TEST((pe - p) == NumValues);
- //ptr - integer
- BOOST_TEST((pe - NumValues) == p);
- //ptr + integer
- BOOST_TEST((p + NumValues) == pe);
- //integer + ptr
- BOOST_TEST((NumValues + p) == pe);
- //indexing
- BOOST_TEST(pint_t(&p[NumValues]) == pe);
- BOOST_TEST(pint_t(&pe[-NumValues]) == p);
- //ptr -= integer
- pint_t p0 = pe;
- p0-= NumValues;
- BOOST_TEST(p == p0);
- //ptr += integer
- pint_t penew = p0;
- penew += NumValues;
- BOOST_TEST(penew == pe);
- //++ptr
- penew = p0;
- for(int j = 0; j != NumValues; ++j, ++penew);
- BOOST_TEST(penew == pe);
- //--ptr
- p0 = pe;
- for(int j = 0; j != NumValues; ++j, --p0);
- BOOST_TEST(p == p0);
- //ptr++
- penew = p0;
- for(int j = 0; j != NumValues; ++j){
- pint_t p_new_copy = penew;
- BOOST_TEST(p_new_copy == penew++);
- }
- //ptr--
- p0 = pe;
- for(int j = 0; j != NumValues; ++j){
- pint_t p0_copy = p0;
- BOOST_TEST(p0_copy == p0--);
- }
- }
- void test_comparison()
- {
- typedef offset_ptr<int> pint_t;
- const int NumValues = 5;
- int values[NumValues];
- //Initialize p
- pint_t p = values;
- BOOST_TEST(p.get() == values);
- //Initialize p + NumValues
- pint_t pe = &values[NumValues];
- BOOST_TEST(pe != p);
- BOOST_TEST(pe.get() == &values[NumValues]);
- //operators
- BOOST_TEST(p != pe);
- BOOST_TEST(p == p);
- BOOST_TEST((p < pe));
- BOOST_TEST((p <= pe));
- BOOST_TEST((pe > p));
- BOOST_TEST((pe >= p));
- }
- bool test_pointer_traits()
- {
- typedef offset_ptr<int> OInt;
- typedef boost::intrusive::pointer_traits< OInt > PTOInt;
- BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::element_type, int>::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::pointer, OInt >::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::difference_type, OInt::difference_type >::value));
- BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::rebind_pointer<double>::type, offset_ptr<double> >::value));
- int dummy;
- OInt oi(&dummy);
- if(boost::intrusive::pointer_traits<OInt>::pointer_to(dummy) != oi){
- return false;
- }
- return true;
- }
- struct node
- {
- offset_ptr<node> next;
- };
- void test_pointer_plus_bits()
- {
- BOOST_STATIC_ASSERT((boost::intrusive::max_pointer_plus_bits< offset_ptr<void>, boost::move_detail::alignment_of<node>::value >::value >= 1U));
- typedef boost::intrusive::pointer_plus_bits< offset_ptr<node>, 1u > ptr_plus_bits;
- node n, n2;
- offset_ptr<node> pnode(&n);
- BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
- BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
- ptr_plus_bits::set_bits(pnode, 1u);
- BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
- BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
- ptr_plus_bits::set_pointer(pnode, &n2);
- BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
- BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
- ptr_plus_bits::set_bits(pnode, 0u);
- BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
- BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
- ptr_plus_bits::set_pointer(pnode, offset_ptr<node>());
- BOOST_TEST(ptr_plus_bits::get_pointer(pnode) ==0);
- BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
- ptr_plus_bits::set_bits(pnode, 1u);
- BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
- BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == 0);
- }
- int main()
- {
- test_types_and_conversions();
- test_base_derived();
- test_arithmetic();
- test_comparison();
- test_pointer_traits();
- test_pointer_plus_bits();
- return ::boost::report_errors();
- }
- #include <boost/interprocess/detail/config_end.hpp>
- /*
- //Offset ptr benchmark
- #include <vector>
- #include <iostream>
- #include <boost/interprocess/managed_shared_memory.hpp>
- #include <boost/interprocess/containers/vector.hpp>
- #include <boost/interprocess/allocators/allocator.hpp>
- #include <boost/timer.hpp>
- #include <cstddef>
- template<class InIt,
- class Ty> inline
- Ty accumulate2(InIt First, InIt Last, Ty Val)
- { // return sum of Val and all in [First, Last)
- for (; First != Last; ++First) //First = First + 1)
- Val = Val + *First;
- return (Val);
- }
- template <typename Vector>
- void time_test(const Vector& vec, std::size_t iterations, const char* label) {
- // assert(!vec.empty())
- boost::timer t;
- typename Vector::const_iterator first = vec.begin();
- typename Vector::value_type result(0);
- while (iterations != 0) {
- result = accumulate2(first, first + vec.size(), result);
- --iterations;
- }
- std::cout << label << t.elapsed() << " " << result << std::endl;
- }
- int main()
- {
- using namespace boost::interprocess;
- typedef allocator<double, managed_shared_memory::segment_manager> alloc_t;
- std::size_t n = 0x1 << 26;
- std::size_t file_size = n * sizeof(double) + 1000000;
- {
- shared_memory_object::remove("MyMappedFile");
- managed_shared_memory segment(open_or_create, "MyMappedFile", file_size);
- shared_memory_object::remove("MyMappedFile");
- alloc_t alloc_inst(segment.get_segment_manager());
- vector<double, alloc_t> v0(n, double(42.42), alloc_inst);
- time_test(v0, 10, "iterator shared: ");
- }
- {
- std::vector<double> v1(n, double(42.42));
- time_test(v1, 10, "iterator non-shared: ");
- }
- return 0;
- }
- */
|