File indexing completed on 2025-09-16 08:37:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_OFFSET_PTR_HPP
0012 #define BOOST_INTERPROCESS_OFFSET_PTR_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 #include <boost/move/detail/type_traits.hpp>
0025
0026 #include <boost/interprocess/interprocess_fwd.hpp>
0027 #include <boost/interprocess/interprocess_printers.hpp>
0028 #include <boost/interprocess/detail/utilities.hpp>
0029 #include <boost/interprocess/detail/cast_tags.hpp>
0030 #include <boost/interprocess/detail/mpl.hpp>
0031 #include <boost/container/detail/type_traits.hpp> //alignment_of, aligned_storage
0032 #include <boost/assert.hpp>
0033 #include <iosfwd>
0034 #include <cstddef>
0035
0036 #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0037 #pragma GCC diagnostic push
0038 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0039 #endif
0040
0041
0042
0043
0044
0045 namespace boost {
0046
0047 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0048
0049
0050 template <class T>
0051 struct has_trivial_destructor;
0052
0053 #endif
0054
0055 namespace interprocess {
0056
0057 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0058
0059 #if !defined( BOOST_NO_CXX11_NULLPTR )
0060 typedef decltype(nullptr) op_nullptr_t;
0061 #else
0062 struct op_nullptr_t
0063 {
0064 void* lx;
0065
0066 struct nat {int bool_conversion;};
0067
0068 BOOST_INTERPROCESS_FORCEINLINE op_nullptr_t() {}
0069
0070 BOOST_INTERPROCESS_FORCEINLINE op_nullptr_t(int nat::*) {}
0071
0072 BOOST_INTERPROCESS_FORCEINLINE operator int nat::*() const { return 0; }
0073
0074 template <class T>
0075 BOOST_INTERPROCESS_FORCEINLINE operator T*() const { return 0; }
0076
0077 template <class T, class U>
0078 BOOST_INTERPROCESS_FORCEINLINE operator T U::* () const { return 0; }
0079
0080 friend BOOST_INTERPROCESS_FORCEINLINE bool operator==(op_nullptr_t, op_nullptr_t) { return true; }
0081 friend BOOST_INTERPROCESS_FORCEINLINE bool operator!=(op_nullptr_t, op_nullptr_t) { return false; }
0082 };
0083
0084 #endif
0085
0086 namespace ipcdetail {
0087
0088
0089 struct op_nat{};
0090
0091 template <class T> struct op_reference
0092 : add_reference<T>
0093 {};
0094
0095 template <> struct op_reference<void>
0096 { typedef op_nat type; };
0097
0098 template <> struct op_reference<void const>
0099 { typedef op_nat type; };
0100
0101 template <> struct op_reference<void volatile>
0102 { typedef op_nat type; };
0103
0104 template <> struct op_reference<void const volatile>
0105 { typedef op_nat type; };
0106
0107 template<class OffsetType, std::size_t OffsetAlignment>
0108 union offset_ptr_internal
0109 {
0110 BOOST_INTERPROCESS_STATIC_ASSERT(sizeof(OffsetType) >= sizeof(uintptr_t));
0111 BOOST_INTERPROCESS_STATIC_ASSERT(boost::move_detail::is_integral<OffsetType>::value && boost::move_detail::is_unsigned<OffsetType>::value);
0112
0113 BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr_internal(OffsetType off)
0114 : m_offset(off)
0115 {}
0116
0117 OffsetType m_offset;
0118
0119 typename ::boost::container::dtl::aligned_storage
0120 < sizeof(OffsetType)
0121 , (OffsetAlignment == offset_type_alignment) ? 1u : OffsetAlignment
0122 >::type alignment_helper;
0123 };
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 #define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
0138 template <class OffsetType>
0139 BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, OffsetType offset)
0140 {
0141 typedef pointer_offset_caster<void*, OffsetType> caster_t;
0142 #ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
0143 if(offset == 1){
0144 return 0;
0145 }
0146 else{
0147 return caster_t(caster_t(this_ptr).offset() + offset).pointer();
0148 }
0149 #else
0150 OffsetType mask = offset == 1;
0151 --mask;
0152 OffsetType target_offset = caster_t(this_ptr).offset() + offset;
0153 target_offset &= mask;
0154 return caster_t(target_offset).pointer();
0155 #endif
0156 }
0157
0158
0159
0160
0161
0162
0163 #define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
0164 template<class OffsetType>
0165 BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
0166 {
0167 typedef pointer_offset_caster<void*, OffsetType> caster_t;
0168 #ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
0169
0170 if(!ptr){
0171 return 1;
0172 }
0173 else{
0174 OffsetType offset = caster_t(ptr).offset()- caster_t(this_ptr).offset();
0175 BOOST_ASSERT(offset != 1);
0176 return offset;
0177 }
0178 #else
0179
0180
0181
0182
0183 OffsetType offset = caster_t(ptr).offset() - caster_t(this_ptr).offset();
0184 --offset;
0185 OffsetType mask = ptr == 0;
0186 --mask;
0187 offset &= mask;
0188 return ++offset;
0189 #endif
0190 }
0191
0192
0193
0194
0195
0196
0197 #define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
0198 template<class OffsetType>
0199 BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset_from_other
0200 (const volatile void *this_ptr, const volatile void *other_ptr, OffsetType other_offset)
0201 {
0202 typedef pointer_offset_caster<void*, OffsetType> caster_t;
0203 #ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
0204 if(other_offset == 1){
0205 return 1;
0206 }
0207 else{
0208 OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset() + other_offset;
0209 BOOST_ASSERT(offset != 1);
0210 return offset;
0211 }
0212 #else
0213 OffsetType mask = other_offset == 1;
0214 --mask;
0215 OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
0216 offset &= mask;
0217 return offset + other_offset;
0218
0219
0220
0221
0222
0223 #endif
0224 }
0225
0226
0227
0228
0229
0230
0231 template<class From, class To>
0232 struct offset_ptr_maintains_address
0233 {
0234 static const bool value = ipcdetail::is_cv_same<From, To>::value
0235 || ipcdetail::is_cv_same<void, To>::value
0236 || ipcdetail::is_cv_same<char, To>::value
0237 ;
0238 };
0239
0240 template<class From, class To, class Ret = void>
0241 struct enable_if_convertible_equal_address
0242 : enable_if_c< ::boost::move_detail::is_convertible<From*, To*>::value
0243 && offset_ptr_maintains_address<From, To>::value
0244 , Ret>
0245 {};
0246
0247 template<class From, class To, class Ret = void>
0248 struct enable_if_convertible_unequal_address
0249 : enable_if_c< ::boost::move_detail::is_convertible<From*, To*>::value
0250 && !offset_ptr_maintains_address<From, To>::value
0251 , Ret>
0252 {};
0253
0254 }
0255 #endif
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
0279 class offset_ptr
0280 {
0281 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0282 typedef offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> self_t;
0283 void unspecified_bool_type_func() const {}
0284 typedef void (self_t::*unspecified_bool_type)() const;
0285 #endif
0286
0287 public:
0288 typedef PointedType element_type;
0289 typedef PointedType * pointer;
0290 typedef typename ipcdetail::
0291 op_reference<PointedType>::type reference;
0292
0293 typedef typename ipcdetail::
0294 remove_volatile<typename ipcdetail::
0295 remove_const<PointedType>::type
0296 >::type value_type;
0297 typedef DifferenceType difference_type;
0298 typedef std::random_access_iterator_tag iterator_category;
0299 typedef OffsetType offset_type;
0300
0301 public:
0302
0303
0304
0305 BOOST_INTERPROCESS_FORCEINLINE offset_ptr() BOOST_NOEXCEPT
0306 : internal(1)
0307 {}
0308
0309
0310
0311 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(op_nullptr_t) BOOST_NOEXCEPT
0312 : internal(1)
0313 {}
0314
0315 #if defined( BOOST_NO_CXX11_NULLPTR )
0316
0317
0318 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(int ipcdetail::op_nat::*) BOOST_NOEXCEPT
0319 : internal(1)
0320 {}
0321 #endif
0322
0323
0324
0325 template <class T>
0326 BOOST_INTERPROCESS_FORCEINLINE offset_ptr( T *ptr
0327 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0328 , typename ipcdetail::enable_if< ::boost::move_detail::is_convertible<T*, PointedType*> >::type * = 0
0329 #endif
0330 ) BOOST_NOEXCEPT
0331 : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr), this))
0332 {}
0333
0334
0335
0336 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr& ptr) BOOST_NOEXCEPT
0337 : internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset))
0338 {}
0339
0340
0341
0342 template<class T2>
0343 BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
0344 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0345 , typename ipcdetail::enable_if_convertible_equal_address<T2, PointedType>::type* = 0
0346 #endif
0347 ) BOOST_NOEXCEPT
0348 : internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()))
0349 {}
0350
0351 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0352
0353 template<class T2>
0354 BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
0355 , typename ipcdetail::enable_if_convertible_unequal_address<T2, PointedType>::type* = 0) BOOST_NOEXCEPT
0356 : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
0357 {}
0358
0359 #endif
0360
0361
0362
0363 template<class T2, class P2, class O2, std::size_t A2>
0364 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::static_cast_tag) BOOST_NOEXCEPT
0365 : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(r.get()), this))
0366 {}
0367
0368
0369
0370 template<class T2, class P2, class O2, std::size_t A2>
0371 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::const_cast_tag) BOOST_NOEXCEPT
0372 : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(const_cast<PointedType*>(r.get()), this))
0373 {}
0374
0375
0376
0377 template<class T2, class P2, class O2, std::size_t A2>
0378 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::dynamic_cast_tag) BOOST_NOEXCEPT
0379 : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(dynamic_cast<PointedType*>(r.get()), this))
0380 {}
0381
0382
0383
0384 template<class T2, class P2, class O2, std::size_t A2>
0385 BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::reinterpret_cast_tag) BOOST_NOEXCEPT
0386 : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(reinterpret_cast<PointedType*>(r.get()), this))
0387 {}
0388
0389
0390
0391 BOOST_INTERPROCESS_FORCEINLINE pointer get() const BOOST_NOEXCEPT
0392 { return static_cast<pointer>(ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset)); }
0393
0394 BOOST_INTERPROCESS_FORCEINLINE offset_type get_offset() const BOOST_NOEXCEPT
0395 { return this->internal.m_offset; }
0396
0397
0398
0399 BOOST_INTERPROCESS_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT
0400 { return this->get(); }
0401
0402
0403
0404 BOOST_INTERPROCESS_FORCEINLINE reference operator*() const BOOST_NOEXCEPT
0405 {
0406 pointer p = this->get();
0407 reference r = *p;
0408 return r;
0409 }
0410
0411
0412
0413 BOOST_INTERPROCESS_FORCEINLINE reference operator[](difference_type idx) const BOOST_NOEXCEPT
0414 { return this->get()[idx]; }
0415
0416
0417
0418
0419 template<class T> BOOST_INTERPROCESS_FORCEINLINE
0420 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0421 typename ipcdetail::enable_if_c
0422 < ::boost::move_detail::is_convertible<T*, PointedType*>::value, offset_ptr&>::type
0423 #else
0424 offset_ptr&
0425 #endif
0426 operator= (T *ptr) BOOST_NOEXCEPT
0427 {
0428 this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr), this);
0429 return *this;
0430 }
0431
0432
0433
0434 BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (const offset_ptr & ptr) BOOST_NOEXCEPT
0435 {
0436 this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset);
0437 return *this;
0438 }
0439
0440
0441
0442 BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (op_nullptr_t) BOOST_NOEXCEPT
0443 {
0444 this->internal.m_offset = 1;
0445 return *this;
0446 }
0447
0448 #if defined( BOOST_NO_CXX11_NULLPTR )
0449
0450
0451 BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (int ipcdetail::op_nat::*) BOOST_NOEXCEPT
0452 {
0453 this->internal.m_offset = 1;
0454 return *this;
0455 }
0456 #endif
0457
0458
0459
0460
0461 template<class T2> BOOST_INTERPROCESS_FORCEINLINE
0462 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0463 typename ipcdetail::enable_if_c
0464 < ::boost::move_detail::is_convertible<T2*, PointedType*>::value, offset_ptr&>::type
0465 #else
0466 offset_ptr&
0467 #endif
0468 operator= (const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr) BOOST_NOEXCEPT
0469 {
0470 this->assign(ptr, ipcdetail::bool_<ipcdetail::offset_ptr_maintains_address<T2, PointedType>::value>());
0471 return *this;
0472 }
0473
0474 public:
0475
0476
0477
0478 BOOST_INTERPROCESS_FORCEINLINE offset_ptr &operator+= (difference_type offset) BOOST_NOEXCEPT
0479 { this->inc_offset(offset * difference_type(sizeof(PointedType))); return *this; }
0480
0481
0482
0483 BOOST_INTERPROCESS_FORCEINLINE offset_ptr &operator-= (difference_type offset) BOOST_NOEXCEPT
0484 { this->dec_offset(offset * difference_type(sizeof(PointedType))); return *this; }
0485
0486
0487
0488 BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator++ (void) BOOST_NOEXCEPT
0489 { this->inc_offset(difference_type(sizeof(PointedType))); return *this; }
0490
0491
0492
0493 BOOST_INTERPROCESS_FORCEINLINE offset_ptr operator++ (int) BOOST_NOEXCEPT
0494 {
0495 offset_ptr tmp(*this);
0496 this->inc_offset(sizeof (PointedType));
0497 return tmp;
0498 }
0499
0500
0501
0502 BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator-- (void) BOOST_NOEXCEPT
0503 { this->dec_offset(sizeof (PointedType)); return *this; }
0504
0505
0506
0507 BOOST_INTERPROCESS_FORCEINLINE offset_ptr operator-- (int) BOOST_NOEXCEPT
0508 {
0509 offset_ptr tmp(*this);
0510 this->dec_offset(sizeof (PointedType));
0511 return tmp;
0512 }
0513
0514
0515
0516 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
0517 BOOST_INTERPROCESS_FORCEINLINE operator unspecified_bool_type() const BOOST_NOEXCEPT
0518 { return this->internal.m_offset != 1? &self_t::unspecified_bool_type_func : 0; }
0519 #else
0520 explicit operator bool() const BOOST_NOEXCEPT
0521 { return this->internal.m_offset != 1; }
0522 #endif
0523
0524
0525
0526 BOOST_INTERPROCESS_FORCEINLINE bool operator! () const BOOST_NOEXCEPT
0527 { return this->internal.m_offset == 1; }
0528
0529
0530
0531 #if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
0532 template <class U>
0533 struct rebind
0534 { typedef offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment> other; };
0535 #else
0536 template <class U>
0537 using rebind = offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment>;
0538 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0539 typedef offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> other;
0540 #endif
0541 #endif
0542
0543
0544
0545 BOOST_INTERPROCESS_FORCEINLINE static offset_ptr pointer_to(typename ipcdetail::op_reference<PointedType>::type r) BOOST_NOEXCEPT
0546 { return offset_ptr(&r); }
0547
0548
0549
0550 BOOST_INTERPROCESS_FORCEINLINE friend offset_ptr operator+(difference_type diff, offset_ptr right) BOOST_NOEXCEPT
0551 { right += diff; return right; }
0552
0553
0554
0555 BOOST_INTERPROCESS_FORCEINLINE friend offset_ptr operator+(offset_ptr left, difference_type diff) BOOST_NOEXCEPT
0556 { left += diff; return left; }
0557
0558
0559
0560 BOOST_INTERPROCESS_FORCEINLINE friend offset_ptr operator-(offset_ptr left, difference_type diff) BOOST_NOEXCEPT
0561 { left -= diff; return left; }
0562
0563
0564
0565 BOOST_INTERPROCESS_FORCEINLINE friend offset_ptr operator-(difference_type diff, offset_ptr right) BOOST_NOEXCEPT
0566 { right -= diff; return right; }
0567
0568
0569
0570 BOOST_INTERPROCESS_FORCEINLINE friend difference_type operator-(const offset_ptr &pt, const offset_ptr &pt2) BOOST_NOEXCEPT
0571 { return difference_type(pt.get()- pt2.get()); }
0572
0573
0574 BOOST_INTERPROCESS_FORCEINLINE friend bool operator== (const offset_ptr &pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0575 { return pt1.get() == pt2.get(); }
0576
0577 BOOST_INTERPROCESS_FORCEINLINE friend bool operator!= (const offset_ptr &pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0578 { return pt1.get() != pt2.get(); }
0579
0580 BOOST_INTERPROCESS_FORCEINLINE friend bool operator<(const offset_ptr &pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0581 { return pt1.get() < pt2.get(); }
0582
0583 BOOST_INTERPROCESS_FORCEINLINE friend bool operator<=(const offset_ptr &pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0584 { return pt1.get() <= pt2.get(); }
0585
0586 BOOST_INTERPROCESS_FORCEINLINE friend bool operator>(const offset_ptr &pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0587 { return pt1.get() > pt2.get(); }
0588
0589 BOOST_INTERPROCESS_FORCEINLINE friend bool operator>=(const offset_ptr &pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0590 { return pt1.get() >= pt2.get(); }
0591
0592
0593 BOOST_INTERPROCESS_FORCEINLINE friend bool operator== (pointer pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0594 { return pt1 == pt2.get(); }
0595
0596 BOOST_INTERPROCESS_FORCEINLINE friend bool operator!= (pointer pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0597 { return pt1 != pt2.get(); }
0598
0599 BOOST_INTERPROCESS_FORCEINLINE friend bool operator<(pointer pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0600 { return pt1 < pt2.get(); }
0601
0602 BOOST_INTERPROCESS_FORCEINLINE friend bool operator<=(pointer pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0603 { return pt1 <= pt2.get(); }
0604
0605 BOOST_INTERPROCESS_FORCEINLINE friend bool operator>(pointer pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0606 { return pt1 > pt2.get(); }
0607
0608 BOOST_INTERPROCESS_FORCEINLINE friend bool operator>=(pointer pt1, const offset_ptr &pt2) BOOST_NOEXCEPT
0609 { return pt1 >= pt2.get(); }
0610
0611
0612 BOOST_INTERPROCESS_FORCEINLINE friend bool operator== (const offset_ptr &pt1, pointer pt2) BOOST_NOEXCEPT
0613 { return pt1.get() == pt2; }
0614
0615 BOOST_INTERPROCESS_FORCEINLINE friend bool operator!= (const offset_ptr &pt1, pointer pt2) BOOST_NOEXCEPT
0616 { return pt1.get() != pt2; }
0617
0618 BOOST_INTERPROCESS_FORCEINLINE friend bool operator<(const offset_ptr &pt1, pointer pt2) BOOST_NOEXCEPT
0619 { return pt1.get() < pt2; }
0620
0621 BOOST_INTERPROCESS_FORCEINLINE friend bool operator<=(const offset_ptr &pt1, pointer pt2) BOOST_NOEXCEPT
0622 { return pt1.get() <= pt2; }
0623
0624 BOOST_INTERPROCESS_FORCEINLINE friend bool operator>(const offset_ptr &pt1, pointer pt2) BOOST_NOEXCEPT
0625 { return pt1.get() > pt2; }
0626
0627 BOOST_INTERPROCESS_FORCEINLINE friend bool operator>=(const offset_ptr &pt1, pointer pt2) BOOST_NOEXCEPT
0628 { return pt1.get() >= pt2; }
0629
0630 BOOST_INTERPROCESS_FORCEINLINE friend void swap(offset_ptr &left, offset_ptr &right) BOOST_NOEXCEPT
0631 {
0632 pointer ptr = right.get();
0633 right = left;
0634 left = ptr;
0635 }
0636
0637 private:
0638 template<class T2>
0639 BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<true>) BOOST_NOEXCEPT
0640 {
0641 this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other<OffsetType>(this, &ptr, ptr.get_offset());
0642 }
0643
0644 template<class T2>
0645 BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<false>) BOOST_NOEXCEPT
0646 {
0647 this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this);
0648 }
0649
0650 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0651 BOOST_INTERPROCESS_FORCEINLINE void inc_offset(DifferenceType bytes) BOOST_NOEXCEPT
0652 { internal.m_offset += OffsetType(bytes); }
0653
0654 BOOST_INTERPROCESS_FORCEINLINE void dec_offset(DifferenceType bytes) BOOST_NOEXCEPT
0655 { internal.m_offset -= OffsetType(bytes); }
0656
0657 ipcdetail::offset_ptr_internal<OffsetType, OffsetAlignment> internal;
0658
0659 public:
0660 BOOST_INTERPROCESS_FORCEINLINE const OffsetType &priv_offset() const BOOST_NOEXCEPT
0661 { return internal.m_offset; }
0662
0663 BOOST_INTERPROCESS_FORCEINLINE OffsetType &priv_offset() BOOST_NOEXCEPT
0664 { return internal.m_offset; }
0665
0666 #endif
0667 };
0668
0669
0670
0671 template<class E, class T, class W, class X, class Y, std::size_t Z>
0672 inline std::basic_ostream<E, T> & operator<<
0673 (std::basic_ostream<E, T> & os, offset_ptr<W, X, Y, Z> const & p)
0674 { return os << p.get_offset(); }
0675
0676
0677
0678 template<class E, class T, class W, class X, class Y, std::size_t Z>
0679 inline std::basic_istream<E, T> & operator>>
0680 (std::basic_istream<E, T> & is, offset_ptr<W, X, Y, Z> & p)
0681 { return is >> p.get_offset(); }
0682
0683
0684 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
0685 BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
0686 static_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
0687 {
0688 return boost::interprocess::offset_ptr<T1, P1, O1, A1>
0689 (r, boost::interprocess::ipcdetail::static_cast_tag());
0690 }
0691
0692
0693 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
0694 BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
0695 const_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
0696 {
0697 return boost::interprocess::offset_ptr<T1, P1, O1, A1>
0698 (r, boost::interprocess::ipcdetail::const_cast_tag());
0699 }
0700
0701
0702 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
0703 BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
0704 dynamic_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
0705 {
0706 return boost::interprocess::offset_ptr<T1, P1, O1, A1>
0707 (r, boost::interprocess::ipcdetail::dynamic_cast_tag());
0708 }
0709
0710
0711 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
0712 BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
0713 reinterpret_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
0714 {
0715 return boost::interprocess::offset_ptr<T1, P1, O1, A1>
0716 (r, boost::interprocess::ipcdetail::reinterpret_cast_tag());
0717 }
0718
0719 }
0720
0721 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0722
0723
0724 template <class T, class P, class O, std::size_t A>
0725 struct has_trivial_destructor< ::boost::interprocess::offset_ptr<T, P, O, A> >
0726 {
0727 static const bool value = true;
0728 };
0729
0730 namespace move_detail {
0731
0732
0733 template <class T, class P, class O, std::size_t A>
0734 struct is_trivially_destructible< ::boost::interprocess::offset_ptr<T, P, O, A> >
0735 {
0736 static const bool value = true;
0737 };
0738
0739 }
0740
0741 namespace interprocess {
0742
0743
0744
0745 template <class T, class P, class O, std::size_t A>
0746 BOOST_INTERPROCESS_FORCEINLINE T * to_raw_pointer(boost::interprocess::offset_ptr<T, P, O, A> const & p) BOOST_NOEXCEPT
0747 { return ipcdetail::to_raw_pointer(p); }
0748
0749 }
0750
0751
0752 #endif
0753 }
0754
0755 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0756
0757 namespace boost{
0758
0759
0760
0761 namespace intrusive {
0762
0763
0764 template<class VoidPointer, std::size_t N>
0765 struct max_pointer_plus_bits;
0766
0767 template<std::size_t OffsetAlignment, class P, class O, std::size_t A>
0768 struct max_pointer_plus_bits<boost::interprocess::offset_ptr<void, P, O, A>, OffsetAlignment>
0769 {
0770
0771
0772 static const std::size_t value = ::boost::interprocess::ipcdetail::ls_zeros<OffsetAlignment>::value - 1;
0773 };
0774
0775
0776 template<class Pointer, std::size_t NumBits>
0777 struct pointer_plus_bits;
0778
0779 template<class T, class P, class O, std::size_t A, std::size_t NumBits>
0780 struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
0781 {
0782 typedef boost::interprocess::offset_ptr<T, P, O, A> pointer;
0783
0784
0785 static const O Mask = ((static_cast<O>(1) << NumBits) - static_cast<O>(1)) << 1;
0786 BOOST_INTERPROCESS_STATIC_ASSERT(0 ==(Mask&1));
0787
0788
0789
0790
0791 BOOST_INTERPROCESS_FORCEINLINE static pointer get_pointer(const pointer &n) BOOST_NOEXCEPT
0792 {
0793 pointer p;
0794 O const tmp_off = n.priv_offset() & ~Mask;
0795 p.priv_offset() = boost::interprocess::ipcdetail::offset_ptr_to_offset_from_other(&p, &n, tmp_off);
0796 return p;
0797 }
0798
0799 BOOST_INTERPROCESS_FORCEINLINE static void set_pointer(pointer &n, const pointer &p) BOOST_NOEXCEPT
0800 {
0801 BOOST_ASSERT(0 == (get_bits)(p));
0802 O const stored_bits = n.priv_offset() & Mask;
0803 n = p;
0804 n.priv_offset() |= stored_bits;
0805 }
0806
0807 BOOST_INTERPROCESS_FORCEINLINE static std::size_t get_bits(const pointer &n) BOOST_NOEXCEPT
0808 {
0809 return std::size_t((n.priv_offset() & Mask) >> 1u);
0810 }
0811
0812 BOOST_INTERPROCESS_FORCEINLINE static void set_bits(pointer &n, std::size_t const b) BOOST_NOEXCEPT
0813 {
0814 BOOST_ASSERT(b < (std::size_t(1) << NumBits));
0815 O tmp = n.priv_offset();
0816 tmp &= ~Mask;
0817 tmp |= O(b << 1u);
0818 n.priv_offset() = tmp;
0819 }
0820 };
0821
0822 }
0823
0824
0825 template<class T, class U>
0826 struct pointer_to_other;
0827
0828
0829 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment, class U>
0830 struct pointer_to_other
0831 < ::boost::interprocess::offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment>, U >
0832 {
0833 typedef ::boost::interprocess::offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment> type;
0834 };
0835
0836 }
0837 #endif
0838
0839 #include <boost/interprocess/detail/config_end.hpp>
0840
0841 #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0842 #pragma GCC diagnostic pop
0843 #endif
0844
0845 #endif