local_counted_base.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. // detail/local_counted_base.hpp
  8. //
  9. // Copyright 2017 Peter Dimov
  10. //
  11. // Distributed under the Boost Software License, Version 1.0. (See
  12. // accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. //
  15. // See http://www.boost.org/libs/smart_ptr/ for documentation.
  16. #include <boost/smart_ptr/detail/shared_count.hpp>
  17. #include <boost/config.hpp>
  18. #include <utility>
  19. namespace boost
  20. {
  21. namespace detail
  22. {
  23. class BOOST_SYMBOL_VISIBLE local_counted_base
  24. {
  25. private:
  26. local_counted_base & operator= ( local_counted_base const & );
  27. private:
  28. // not 'int' or 'unsigned' to avoid aliasing and enable optimizations
  29. enum count_type { min_ = 0, initial_ = 1, max_ = 2147483647 };
  30. count_type local_use_count_;
  31. public:
  32. constexpr local_counted_base() noexcept: local_use_count_( initial_ )
  33. {
  34. }
  35. constexpr local_counted_base( local_counted_base const & ) noexcept: local_use_count_( initial_ )
  36. {
  37. }
  38. virtual ~local_counted_base() /*noexcept*/
  39. {
  40. }
  41. virtual void local_cb_destroy() noexcept = 0;
  42. virtual boost::detail::shared_count local_cb_get_shared_count() const noexcept = 0;
  43. void add_ref() noexcept
  44. {
  45. #if !defined(__NVCC__)
  46. #if defined( __has_builtin )
  47. # if __has_builtin( __builtin_assume )
  48. __builtin_assume( local_use_count_ >= 1 );
  49. # endif
  50. #endif
  51. #endif
  52. local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
  53. }
  54. void release() noexcept
  55. {
  56. local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
  57. if( local_use_count_ == 0 )
  58. {
  59. local_cb_destroy();
  60. }
  61. }
  62. long local_use_count() const noexcept
  63. {
  64. return local_use_count_;
  65. }
  66. };
  67. class BOOST_SYMBOL_VISIBLE local_counted_impl: public local_counted_base
  68. {
  69. private:
  70. local_counted_impl( local_counted_impl const & );
  71. private:
  72. shared_count pn_;
  73. public:
  74. explicit local_counted_impl( shared_count const& pn ) noexcept: pn_( pn )
  75. {
  76. }
  77. explicit local_counted_impl( shared_count && pn ) noexcept: pn_( std::move(pn) )
  78. {
  79. }
  80. void local_cb_destroy() noexcept override
  81. {
  82. delete this;
  83. }
  84. boost::detail::shared_count local_cb_get_shared_count() const noexcept override
  85. {
  86. return pn_;
  87. }
  88. };
  89. class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base
  90. {
  91. public:
  92. shared_count pn_;
  93. void local_cb_destroy() noexcept override
  94. {
  95. shared_count().swap( pn_ );
  96. }
  97. boost::detail::shared_count local_cb_get_shared_count() const noexcept override
  98. {
  99. return pn_;
  100. }
  101. };
  102. } // namespace detail
  103. } // namespace boost
  104. #endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED