annotate DEPENDENCIES/generic/include/boost/circular_buffer/debug.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Debug support for the circular buffer library.
Chris@16 2
Chris@16 3 // Copyright (c) 2003-2008 Jan Gaspar
Chris@16 4
Chris@16 5 // Use, modification, and distribution is subject to the Boost Software
Chris@16 6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
Chris@16 10 #define BOOST_CIRCULAR_BUFFER_DEBUG_HPP
Chris@16 11
Chris@101 12 #if defined(_MSC_VER)
Chris@16 13 #pragma once
Chris@16 14 #endif
Chris@16 15
Chris@101 16 #if BOOST_CB_ENABLE_DEBUG
Chris@101 17 #include <cstring>
Chris@101 18
Chris@101 19 #if defined(BOOST_NO_STDC_NAMESPACE)
Chris@101 20 namespace std {
Chris@101 21 using ::memset;
Chris@101 22 }
Chris@101 23 #endif
Chris@101 24
Chris@101 25 #endif // BOOST_CB_ENABLE_DEBUG
Chris@16 26 namespace boost {
Chris@16 27
Chris@16 28 namespace cb_details {
Chris@16 29
Chris@16 30 #if BOOST_CB_ENABLE_DEBUG
Chris@16 31
Chris@16 32 // The value the uninitialized memory is filled with.
Chris@16 33 const int UNINITIALIZED = 0xcc;
Chris@16 34
Chris@101 35 template <class T>
Chris@101 36 inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
Chris@101 37 std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes);
Chris@101 38 }
Chris@101 39
Chris@101 40 template <class T>
Chris@101 41 inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT {
Chris@101 42 // Do nothing
Chris@101 43 }
Chris@101 44
Chris@101 45
Chris@16 46 class debug_iterator_registry;
Chris@16 47
Chris@16 48 /*!
Chris@16 49 \class debug_iterator_base
Chris@16 50 \brief Registers/unregisters iterators into the registry of valid iterators.
Chris@16 51
Chris@16 52 This class is intended to be a base class of an iterator.
Chris@16 53 */
Chris@16 54 class debug_iterator_base {
Chris@16 55
Chris@16 56 private:
Chris@16 57 // Members
Chris@16 58
Chris@16 59 //! Iterator registry.
Chris@16 60 mutable const debug_iterator_registry* m_registry;
Chris@16 61
Chris@16 62 //! Next iterator in the iterator chain.
Chris@16 63 mutable const debug_iterator_base* m_next;
Chris@16 64
Chris@16 65 public:
Chris@16 66 // Construction/destruction
Chris@16 67
Chris@16 68 //! Default constructor.
Chris@16 69 debug_iterator_base();
Chris@16 70
Chris@16 71 //! Constructor taking the iterator registry as a parameter.
Chris@16 72 debug_iterator_base(const debug_iterator_registry* registry);
Chris@16 73
Chris@16 74 //! Copy constructor.
Chris@16 75 debug_iterator_base(const debug_iterator_base& rhs);
Chris@16 76
Chris@16 77 //! Destructor.
Chris@16 78 ~debug_iterator_base();
Chris@16 79
Chris@16 80 // Methods
Chris@16 81
Chris@16 82 //! Assign operator.
Chris@16 83 debug_iterator_base& operator = (const debug_iterator_base& rhs);
Chris@16 84
Chris@16 85 //! Is the iterator valid?
Chris@16 86 bool is_valid(const debug_iterator_registry* registry) const;
Chris@16 87
Chris@16 88 //! Invalidate the iterator.
Chris@16 89 /*!
Chris@16 90 \note The method is const in order to invalidate const iterators, too.
Chris@16 91 */
Chris@16 92 void invalidate() const;
Chris@16 93
Chris@16 94 //! Return the next iterator in the iterator chain.
Chris@16 95 const debug_iterator_base* next() const;
Chris@16 96
Chris@16 97 //! Set the next iterator in the iterator chain.
Chris@16 98 /*!
Chris@16 99 \note The method is const in order to set a next iterator to a const iterator, too.
Chris@16 100 */
Chris@16 101 void set_next(const debug_iterator_base* it) const;
Chris@16 102
Chris@16 103 private:
Chris@16 104 // Helpers
Chris@16 105
Chris@16 106 //! Register self as a valid iterator.
Chris@16 107 void register_self();
Chris@16 108
Chris@16 109 //! Unregister self from valid iterators.
Chris@16 110 void unregister_self();
Chris@16 111 };
Chris@16 112
Chris@16 113 /*!
Chris@16 114 \class debug_iterator_registry
Chris@16 115 \brief Registry of valid iterators.
Chris@16 116
Chris@16 117 This class is intended to be a base class of a container.
Chris@16 118 */
Chris@16 119 class debug_iterator_registry {
Chris@16 120
Chris@16 121 //! Pointer to the chain of valid iterators.
Chris@16 122 mutable const debug_iterator_base* m_iterators;
Chris@16 123
Chris@16 124 public:
Chris@16 125 // Methods
Chris@16 126
Chris@16 127 //! Default constructor.
Chris@16 128 debug_iterator_registry() : m_iterators(0) {}
Chris@16 129
Chris@16 130 //! Register an iterator into the list of valid iterators.
Chris@16 131 /*!
Chris@16 132 \note The method is const in order to register iterators into const containers, too.
Chris@16 133 */
Chris@16 134 void register_iterator(const debug_iterator_base* it) const {
Chris@16 135 it->set_next(m_iterators);
Chris@16 136 m_iterators = it;
Chris@16 137 }
Chris@16 138
Chris@16 139 //! Unregister an iterator from the list of valid iterators.
Chris@16 140 /*!
Chris@16 141 \note The method is const in order to unregister iterators from const containers, too.
Chris@16 142 */
Chris@16 143 void unregister_iterator(const debug_iterator_base* it) const {
Chris@16 144 const debug_iterator_base* previous = 0;
Chris@16 145 for (const debug_iterator_base* p = m_iterators; p != it; previous = p, p = p->next()) {}
Chris@16 146 remove(it, previous);
Chris@16 147 }
Chris@16 148
Chris@16 149 //! Invalidate every iterator pointing to the same element as the iterator passed as a parameter.
Chris@16 150 template <class Iterator>
Chris@16 151 void invalidate_iterators(const Iterator& it) {
Chris@16 152 const debug_iterator_base* previous = 0;
Chris@16 153 for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
Chris@16 154 if (((Iterator*)p)->m_it == it.m_it) {
Chris@16 155 p->invalidate();
Chris@16 156 remove(p, previous);
Chris@16 157 continue;
Chris@16 158 }
Chris@16 159 previous = p;
Chris@16 160 }
Chris@16 161 }
Chris@16 162
Chris@16 163 //! Invalidate all iterators except an iterator poining to the same element as the iterator passed as a parameter.
Chris@16 164 template <class Iterator>
Chris@16 165 void invalidate_iterators_except(const Iterator& it) {
Chris@16 166 const debug_iterator_base* previous = 0;
Chris@16 167 for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
Chris@16 168 if (((Iterator*)p)->m_it != it.m_it) {
Chris@16 169 p->invalidate();
Chris@16 170 remove(p, previous);
Chris@16 171 continue;
Chris@16 172 }
Chris@16 173 previous = p;
Chris@16 174 }
Chris@16 175 }
Chris@16 176
Chris@16 177 //! Invalidate all iterators.
Chris@16 178 void invalidate_all_iterators() {
Chris@16 179 for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next())
Chris@16 180 p->invalidate();
Chris@16 181 m_iterators = 0;
Chris@16 182 }
Chris@16 183
Chris@16 184 private:
Chris@16 185 // Helpers
Chris@16 186
Chris@16 187 //! Remove the current iterator from the iterator chain.
Chris@16 188 void remove(const debug_iterator_base* current,
Chris@16 189 const debug_iterator_base* previous) const {
Chris@16 190 if (previous == 0)
Chris@16 191 m_iterators = m_iterators->next();
Chris@16 192 else
Chris@16 193 previous->set_next(current->next());
Chris@16 194 }
Chris@16 195 };
Chris@16 196
Chris@16 197 // Implementation of the debug_iterator_base methods.
Chris@16 198
Chris@16 199 inline debug_iterator_base::debug_iterator_base() : m_registry(0), m_next(0) {}
Chris@16 200
Chris@16 201 inline debug_iterator_base::debug_iterator_base(const debug_iterator_registry* registry)
Chris@16 202 : m_registry(registry), m_next(0) {
Chris@16 203 register_self();
Chris@16 204 }
Chris@16 205
Chris@16 206 inline debug_iterator_base::debug_iterator_base(const debug_iterator_base& rhs)
Chris@16 207 : m_registry(rhs.m_registry), m_next(0) {
Chris@16 208 register_self();
Chris@16 209 }
Chris@16 210
Chris@16 211 inline debug_iterator_base::~debug_iterator_base() { unregister_self(); }
Chris@16 212
Chris@16 213 inline debug_iterator_base& debug_iterator_base::operator = (const debug_iterator_base& rhs) {
Chris@16 214 if (m_registry == rhs.m_registry)
Chris@16 215 return *this;
Chris@16 216 unregister_self();
Chris@16 217 m_registry = rhs.m_registry;
Chris@16 218 register_self();
Chris@16 219 return *this;
Chris@16 220 }
Chris@16 221
Chris@16 222 inline bool debug_iterator_base::is_valid(const debug_iterator_registry* registry) const {
Chris@16 223 return m_registry == registry;
Chris@16 224 }
Chris@16 225
Chris@16 226 inline void debug_iterator_base::invalidate() const { m_registry = 0; }
Chris@16 227
Chris@16 228 inline const debug_iterator_base* debug_iterator_base::next() const { return m_next; }
Chris@16 229
Chris@16 230 inline void debug_iterator_base::set_next(const debug_iterator_base* it) const { m_next = it; }
Chris@16 231
Chris@16 232 inline void debug_iterator_base::register_self() {
Chris@16 233 if (m_registry != 0)
Chris@16 234 m_registry->register_iterator(this);
Chris@16 235 }
Chris@16 236
Chris@16 237 inline void debug_iterator_base::unregister_self() {
Chris@16 238 if (m_registry != 0)
Chris@16 239 m_registry->unregister_iterator(this);
Chris@16 240 }
Chris@16 241
Chris@16 242 #endif // #if BOOST_CB_ENABLE_DEBUG
Chris@16 243
Chris@16 244 } // namespace cb_details
Chris@16 245
Chris@16 246 } // namespace boost
Chris@16 247
Chris@16 248 #endif // #if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)