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