libstdc++
safe_unordered_base.h
Go to the documentation of this file.
1 // Safe container/iterator base implementation -*- C++ -*-
2 
3 // Copyright (C) 2011-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file debug/safe_unordered_base.h
26  * This file is a GNU debug extension to the Standard C++ Library.
27  */
28 
29 #ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_BASE_H
30 #define _GLIBCXX_DEBUG_SAFE_UNORDERED_BASE_H 1
31 
32 #include <debug/safe_base.h>
33 
34 namespace __gnu_debug
35 {
36  class _Safe_unordered_container_base;
37 
38  /** \brief Basic functionality for a @a safe iterator.
39  *
40  * The %_Safe_local_iterator_base base class implements the functionality
41  * of a safe local iterator that is not specific to a particular iterator
42  * type. It contains a pointer back to the container it references
43  * along with iterator version information and pointers to form a
44  * doubly-linked list of local iterators referenced by the container.
45  *
46  * This class must not perform any operations that can throw an
47  * exception, or the exception guarantees of derived iterators will
48  * be broken.
49  */
51  {
52  protected:
53  /** Initializes the iterator and makes it singular. */
55  { }
56 
57  /** Initialize the iterator to reference the container pointed to
58  * by @p __seq. @p __constant is true when we are initializing a
59  * constant local iterator, and false if it is a mutable local iterator.
60  * Note that @p __seq may be NULL, in which case the iterator will be
61  * singular. Otherwise, the iterator will reference @p __seq and
62  * be nonsingular.
63  */
64  _Safe_local_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
65  { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); }
66 
67  /** Initializes the iterator to reference the same container that
68  @p __x does. @p __constant is true if this is a constant
69  iterator, and false if it is mutable. */
71  bool __constant)
72  { this->_M_attach(__x._M_sequence, __constant); }
73 
74  ~_Safe_local_iterator_base() { this->_M_detach(); }
75 
77  _M_get_container() const noexcept;
78 
79  /** Attaches this iterator to the given container, detaching it
80  * from whatever container it was attached to originally. If the
81  * new container is the NULL pointer, the iterator is left
82  * unattached.
83  */
84  void
85  _M_attach(_Safe_sequence_base* __seq, bool __constant);
86 
87  /** Likewise, but not thread-safe. */
88  void
89  _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
90 
91  /** Detach the iterator for whatever container it is attached to,
92  * if any.
93  */
94  void
95  _M_detach();
96 
97  /** Likewise, but not thread-safe. */
98  void
99  _M_detach_single() throw ();
100  };
101 
102  /**
103  * @brief Base class that supports tracking of local iterators that
104  * reference an unordered container.
105  *
106  * The %_Safe_unordered_container_base class provides basic support for
107  * tracking iterators into an unordered container. Containers that track
108  * iterators must derived from %_Safe_unordered_container_base publicly, so
109  * that safe iterators (which inherit _Safe_iterator_base) can
110  * attach to them. This class contains four linked lists of
111  * iterators, one for constant iterators, one for mutable
112  * iterators, one for constant local iterators, one for mutable local
113  * iterators and a version number that allows very fast
114  * invalidation of all iterators that reference the container.
115  *
116  * This class must ensure that no operation on it may throw an
117  * exception, otherwise @a safe containers may fail to provide the
118  * exception-safety guarantees required by the C++ standard.
119  */
121  {
122  friend class _Safe_local_iterator_base;
123  typedef _Safe_sequence_base _Base;
124 
125  public:
126  /// The list of mutable local iterators that reference this container
128 
129  /// The list of constant local iterators that reference this container
131 
132  protected:
133  // Initialize with a version number of 1 and no iterators
135  : _M_local_iterators(nullptr), _M_const_local_iterators(nullptr)
136  { }
137 
138  // Copy constructor does not copy iterators.
140  noexcept
142 
143  // When moved unordered containers iterators are swapped.
145  noexcept
147  { this->_M_swap(__x); }
148 
149  /** Notify all iterators that reference this container that the
150  container is being destroyed. */
152  { this->_M_detach_all(); }
153 
154  /** Detach all iterators, leaving them singular. */
155  void
156  _M_detach_all();
157 
158  /** Swap this container with the given container. This operation
159  * also swaps ownership of the iterators, so that when the
160  * operation is complete all iterators that originally referenced
161  * one container now reference the other container.
162  */
163  void
164  _M_swap(_Safe_unordered_container_base& __x) noexcept;
165 
166  private:
167  /** Attach an iterator to this container. */
168  void
169  _M_attach_local(_Safe_iterator_base* __it, bool __constant);
170 
171  /** Likewise but not thread safe. */
172  void
173  _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ();
174 
175  /** Detach an iterator from this container */
176  void
177  _M_detach_local(_Safe_iterator_base* __it);
178 
179  /** Likewise but not thread safe. */
180  void
181  _M_detach_local_single(_Safe_iterator_base* __it) throw ();
182  };
183 } // namespace __gnu_debug
184 
185 #endif
_Safe_iterator_base * _M_const_local_iterators
The list of constant local iterators that reference this container.
_Safe_local_iterator_base(const _Safe_sequence_base *__seq, bool __constant)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
Base class that supports tracking of iterators that reference a sequence.
Definition: safe_base.h:188
_Safe_local_iterator_base(const _Safe_local_iterator_base &__x, bool __constant)
_Safe_iterator_base * _M_local_iterators
The list of mutable local iterators that reference this container.
Base class that supports tracking of local iterators that reference an unordered container.
GNU debug classes for public use.
Basic functionality for a safe iterator.
Basic functionality for a safe iterator.
Definition: safe_base.h:50
_Safe_sequence_base * _M_sequence
Definition: safe_base.h:57
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)