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