libstdc++
safe_base.h
Go to the documentation of this file.
1
// Safe sequence/iterator base implementation -*- C++ -*-
2
3
// Copyright (C) 2003, 2004, 2005, 2006, 2009
4
// Free Software Foundation, Inc.
5
//
6
// This file is part of the GNU ISO C++ Library. This library is free
7
// software; you can redistribute it and/or modify it under the
8
// terms of the GNU General Public License as published by the
9
// Free Software Foundation; either version 3, or (at your option)
10
// any later version.
11
12
// This library is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
16
17
// Under Section 7 of GPL version 3, you are granted additional
18
// permissions described in the GCC Runtime Library Exception, version
19
// 3.1, as published by the Free Software Foundation.
20
21
// You should have received a copy of the GNU General Public License and
22
// a copy of the GCC Runtime Library Exception along with this program;
23
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24
// <http://www.gnu.org/licenses/>.
25
26
/** @file debug/safe_base.h
27
* This file is a GNU debug extension to the Standard C++ Library.
28
*/
29
30
#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H
31
#define _GLIBCXX_DEBUG_SAFE_BASE_H 1
32
33
#include <
ext/concurrence.h
>
34
35
namespace
__gnu_debug
36
{
37
class
_Safe_sequence_base;
38
39
/** \brief Basic functionality for a "safe" iterator.
40
*
41
* The %_Safe_iterator_base base class implements the functionality
42
* of a safe iterator that is not specific to a particular iterator
43
* type. It contains a pointer back to the sequence it references
44
* along with iterator version information and pointers to form a
45
* doubly-linked list of iterators referenced by the container.
46
*
47
* This class must not perform any operations that can throw an
48
* exception, or the exception guarantees of derived iterators will
49
* be broken.
50
*/
51
class
_Safe_iterator_base
52
{
53
public
:
54
/** The sequence this iterator references; may be NULL to indicate
55
a singular iterator. */
56
_Safe_sequence_base
*
_M_sequence
;
57
58
/** The version number of this iterator. The sentinel value 0 is
59
* used to indicate an invalidated iterator (i.e., one that is
60
* singular because of an operation on the container). This
61
* version number must equal the version number in the sequence
62
* referenced by _M_sequence for the iterator to be
63
* non-singular.
64
*/
65
unsigned
int
_M_version
;
66
67
/** Pointer to the previous iterator in the sequence's list of
68
iterators. Only valid when _M_sequence != NULL. */
69
_Safe_iterator_base
*
_M_prior
;
70
71
/** Pointer to the next iterator in the sequence's list of
72
iterators. Only valid when _M_sequence != NULL. */
73
_Safe_iterator_base
*
_M_next
;
74
75
protected
:
76
/** Initializes the iterator and makes it singular. */
77
_Safe_iterator_base
()
78
:
_M_sequence
(0),
_M_version
(0),
_M_prior
(0),
_M_next
(0)
79
{ }
80
81
/** Initialize the iterator to reference the sequence pointed to
82
* by @p__seq. @p __constant is true when we are initializing a
83
* constant iterator, and false if it is a mutable iterator. Note
84
* that @p __seq may be NULL, in which case the iterator will be
85
* singular. Otherwise, the iterator will reference @p __seq and
86
* be nonsingular.
87
*/
88
_Safe_iterator_base
(
const
_Safe_sequence_base
* __seq,
bool
__constant)
89
:
_M_sequence
(0),
_M_version
(0),
_M_prior
(0),
_M_next
(0)
90
{ this->
_M_attach
(const_cast<_Safe_sequence_base*>(__seq), __constant); }
91
92
/** Initializes the iterator to reference the same sequence that
93
@p __x does. @p __constant is true if this is a constant
94
iterator, and false if it is mutable. */
95
_Safe_iterator_base
(
const
_Safe_iterator_base
& __x,
bool
__constant)
96
:
_M_sequence
(0),
_M_version
(0),
_M_prior
(0),
_M_next
(0)
97
{ this->
_M_attach
(__x.
_M_sequence
, __constant); }
98
99
_Safe_iterator_base
&
100
operator=(
const
_Safe_iterator_base
&);
101
102
explicit
103
_Safe_iterator_base
(
const
_Safe_iterator_base
&);
104
105
~
_Safe_iterator_base
() { this->
_M_detach
(); }
106
107
/** For use in _Safe_iterator. */
108
__gnu_cxx::__mutex&
_M_get_mutex
();
109
110
public
:
111
/** Attaches this iterator to the given sequence, detaching it
112
* from whatever sequence it was attached to originally. If the
113
* new sequence is the NULL pointer, the iterator is left
114
* unattached.
115
*/
116
void
_M_attach
(_Safe_sequence_base* __seq,
bool
__constant);
117
118
/** Likewise, but not thread-safe. */
119
void
_M_attach_single
(_Safe_sequence_base* __seq,
bool
__constant);
120
121
/** Detach the iterator for whatever sequence it is attached to,
122
* if any.
123
*/
124
void
_M_detach
();
125
126
/** Likewise, but not thread-safe. */
127
void
_M_detach_single
();
128
129
/** Determines if we are attached to the given sequence. */
130
bool
_M_attached_to
(
const
_Safe_sequence_base
* __seq)
const
131
{
return
_M_sequence
== __seq; }
132
133
/** Is this iterator singular? */
134
bool
_M_singular
()
const
;
135
136
/** Can we compare this iterator to the given iterator @p __x?
137
Returns true if both iterators are nonsingular and reference
138
the same sequence. */
139
bool
_M_can_compare
(
const
_Safe_iterator_base
& __x)
const
;
140
};
141
142
/**
143
* @brief Base class that supports tracking of iterators that
144
* reference a sequence.
145
*
146
* The %_Safe_sequence_base class provides basic support for
147
* tracking iterators into a sequence. Sequences that track
148
* iterators must derived from %_Safe_sequence_base publicly, so
149
* that safe iterators (which inherit _Safe_iterator_base) can
150
* attach to them. This class contains two linked lists of
151
* iterators, one for constant iterators and one for mutable
152
* iterators, and a version number that allows very fast
153
* invalidation of all iterators that reference the container.
154
*
155
* This class must ensure that no operation on it may throw an
156
* exception, otherwise "safe" sequences may fail to provide the
157
* exception-safety guarantees required by the C++ standard.
158
*/
159
class
_Safe_sequence_base
160
{
161
public
:
162
/// The list of mutable iterators that reference this container
163
_Safe_iterator_base
*
_M_iterators
;
164
165
/// The list of constant iterators that reference this container
166
_Safe_iterator_base
*
_M_const_iterators
;
167
168
/// The container version number. This number may never be 0.
169
mutable
unsigned
int
_M_version
;
170
171
protected
:
172
// Initialize with a version number of 1 and no iterators
173
_Safe_sequence_base
()
174
:
_M_iterators
(0),
_M_const_iterators
(0),
_M_version
(1)
175
{ }
176
177
/** Notify all iterators that reference this sequence that the
178
sequence is being destroyed. */
179
~_Safe_sequence_base
()
180
{ this->
_M_detach_all
(); }
181
182
/** Detach all iterators, leaving them singular. */
183
void
184
_M_detach_all
();
185
186
/** Detach all singular iterators.
187
* @post for all iterators i attached to this sequence,
188
* i->_M_version == _M_version.
189
*/
190
void
191
_M_detach_singular
();
192
193
/** Revalidates all attached singular iterators. This method may
194
* be used to validate iterators that were invalidated before
195
* (but for some reason, such as an exception, need to become
196
* valid again).
197
*/
198
void
199
_M_revalidate_singular
();
200
201
/** Swap this sequence with the given sequence. This operation
202
* also swaps ownership of the iterators, so that when the
203
* operation is complete all iterators that originally referenced
204
* one container now reference the other container.
205
*/
206
void
207
_M_swap
(
_Safe_sequence_base
& __x);
208
209
/** For use in _Safe_sequence. */
210
__gnu_cxx::__mutex&
_M_get_mutex
();
211
212
public
:
213
/** Invalidates all iterators. */
214
void
215
_M_invalidate_all
()
const
216
{
if
(++
_M_version
== 0)
_M_version
= 1; }
217
};
218
}
// namespace __gnu_debug
219
220
#endif
include
debug
safe_base.h
Generated on Thu May 9 2013 11:47:34 for libstdc++ by
1.8.1.2