annotate DEPENDENCIES/generic/include/boost/smart_ptr/intrusive_ref_counter.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*
Chris@16 2 * Copyright Andrey Semashev 2007 - 2013.
Chris@16 3 * Distributed under the Boost Software License, Version 1.0.
Chris@16 4 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 */
Chris@16 7 /*!
Chris@16 8 * \file intrusive_ref_counter.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 12.03.2009
Chris@16 11 *
Chris@16 12 * This header contains a reference counter class for \c intrusive_ptr.
Chris@16 13 */
Chris@16 14
Chris@16 15 #ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
Chris@16 16 #define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
Chris@16 17
Chris@16 18 #include <boost/config.hpp>
Chris@16 19 #include <boost/smart_ptr/detail/atomic_count.hpp>
Chris@16 20
Chris@16 21 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 22 #pragma once
Chris@16 23 #endif
Chris@16 24
Chris@16 25 #if defined(_MSC_VER)
Chris@16 26 #pragma warning(push)
Chris@16 27 // This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
Chris@16 28 // 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
Chris@16 29 // Note that there is no inline specifier in the declarations.
Chris@16 30 #pragma warning(disable: 4396)
Chris@16 31 #endif
Chris@16 32
Chris@16 33 namespace boost {
Chris@16 34
Chris@16 35 namespace sp_adl_block {
Chris@16 36
Chris@16 37 /*!
Chris@16 38 * \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
Chris@16 39 *
Chris@16 40 * The policy instructs the \c intrusive_ref_counter base class to implement
Chris@16 41 * a reference counter suitable for single threaded use only. Pointers to the same
Chris@16 42 * object with this kind of reference counter must not be used by different threads.
Chris@16 43 */
Chris@16 44 struct thread_unsafe_counter
Chris@16 45 {
Chris@16 46 typedef unsigned int type;
Chris@16 47
Chris@16 48 static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
Chris@16 49 {
Chris@16 50 return counter;
Chris@16 51 }
Chris@16 52
Chris@16 53 static void increment(unsigned int& counter) BOOST_NOEXCEPT
Chris@16 54 {
Chris@16 55 ++counter;
Chris@16 56 }
Chris@16 57
Chris@16 58 static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
Chris@16 59 {
Chris@16 60 return --counter;
Chris@16 61 }
Chris@16 62 };
Chris@16 63
Chris@16 64 /*!
Chris@16 65 * \brief Thread safe reference counter policy for \c intrusive_ref_counter
Chris@16 66 *
Chris@16 67 * The policy instructs the \c intrusive_ref_counter base class to implement
Chris@16 68 * a thread-safe reference counter, if the target platform supports multithreading.
Chris@16 69 */
Chris@16 70 struct thread_safe_counter
Chris@16 71 {
Chris@16 72 typedef boost::detail::atomic_count type;
Chris@16 73
Chris@16 74 static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
Chris@16 75 {
Chris@16 76 return static_cast< unsigned int >(static_cast< long >(counter));
Chris@16 77 }
Chris@16 78
Chris@16 79 static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
Chris@16 80 {
Chris@16 81 ++counter;
Chris@16 82 }
Chris@16 83
Chris@16 84 static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
Chris@16 85 {
Chris@16 86 return --counter;
Chris@16 87 }
Chris@16 88 };
Chris@16 89
Chris@16 90 template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
Chris@16 91 class intrusive_ref_counter;
Chris@16 92
Chris@16 93 template< typename DerivedT, typename CounterPolicyT >
Chris@16 94 void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
Chris@16 95 template< typename DerivedT, typename CounterPolicyT >
Chris@16 96 void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
Chris@16 97
Chris@16 98 /*!
Chris@16 99 * \brief A reference counter base class
Chris@16 100 *
Chris@16 101 * This base class can be used with user-defined classes to add support
Chris@16 102 * for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
Chris@16 103 * Upon releasing the last \c intrusive_ptr referencing the object
Chris@16 104 * derived from the \c intrusive_ref_counter class, operator \c delete
Chris@16 105 * is automatically called on the pointer to the object.
Chris@16 106 *
Chris@16 107 * The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
Chris@16 108 */
Chris@16 109 template< typename DerivedT, typename CounterPolicyT >
Chris@16 110 class intrusive_ref_counter
Chris@16 111 {
Chris@16 112 private:
Chris@16 113 //! Reference counter type
Chris@16 114 typedef typename CounterPolicyT::type counter_type;
Chris@16 115 //! Reference counter
Chris@16 116 mutable counter_type m_ref_counter;
Chris@16 117
Chris@16 118 public:
Chris@16 119 /*!
Chris@16 120 * Default constructor
Chris@16 121 *
Chris@16 122 * \post <tt>use_count() == 0</tt>
Chris@16 123 */
Chris@16 124 intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
Chris@16 125 {
Chris@16 126 }
Chris@16 127
Chris@16 128 /*!
Chris@16 129 * Copy constructor
Chris@16 130 *
Chris@16 131 * \post <tt>use_count() == 0</tt>
Chris@16 132 */
Chris@16 133 intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
Chris@16 134 {
Chris@16 135 }
Chris@16 136
Chris@16 137 /*!
Chris@16 138 * Assignment
Chris@16 139 *
Chris@16 140 * \post The reference counter is not modified after assignment
Chris@16 141 */
Chris@16 142 intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
Chris@16 143
Chris@16 144 /*!
Chris@16 145 * \return The reference counter
Chris@16 146 */
Chris@16 147 unsigned int use_count() const BOOST_NOEXCEPT
Chris@16 148 {
Chris@16 149 return CounterPolicyT::load(m_ref_counter);
Chris@16 150 }
Chris@16 151
Chris@16 152 protected:
Chris@16 153 /*!
Chris@16 154 * Destructor
Chris@16 155 */
Chris@16 156 BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
Chris@16 157
Chris@16 158 friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
Chris@16 159 friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
Chris@16 160 };
Chris@16 161
Chris@16 162 template< typename DerivedT, typename CounterPolicyT >
Chris@16 163 inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
Chris@16 164 {
Chris@16 165 CounterPolicyT::increment(p->m_ref_counter);
Chris@16 166 }
Chris@16 167
Chris@16 168 template< typename DerivedT, typename CounterPolicyT >
Chris@16 169 inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
Chris@16 170 {
Chris@16 171 if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
Chris@16 172 delete static_cast< const DerivedT* >(p);
Chris@16 173 }
Chris@16 174
Chris@16 175 } // namespace sp_adl_block
Chris@16 176
Chris@16 177 using sp_adl_block::intrusive_ref_counter;
Chris@16 178 using sp_adl_block::thread_unsafe_counter;
Chris@16 179 using sp_adl_block::thread_safe_counter;
Chris@16 180
Chris@16 181 } // namespace boost
Chris@16 182
Chris@16 183 #if defined(_MSC_VER)
Chris@16 184 #pragma warning(pop)
Chris@16 185 #endif
Chris@16 186
Chris@16 187 #endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_