Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5134 serge 1
// Debugging set implementation -*- C++ -*-
2
 
3
// Copyright (C) 2003-2013 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
// .
24
 
25
/** @file debug/set.h
26
 *  This file is a GNU debug extension to the Standard C++ Library.
27
 */
28
 
29
#ifndef _GLIBCXX_DEBUG_SET_H
30
#define _GLIBCXX_DEBUG_SET_H 1
31
 
32
#include 
33
#include 
34
#include 
35
 
36
namespace std _GLIBCXX_VISIBILITY(default)
37
{
38
namespace __debug
39
{
40
  /// Class std::set with safety/checking/debug instrumentation.
41
  template,
42
	   typename _Allocator = std::allocator<_Key> >
43
    class set
44
    : public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>,
45
      public __gnu_debug::_Safe_sequence >
46
    {
47
      typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base;
48
 
49
      typedef typename _Base::const_iterator _Base_const_iterator;
50
      typedef typename _Base::iterator _Base_iterator;
51
      typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
52
    public:
53
      // types:
54
      typedef _Key				    key_type;
55
      typedef _Key				    value_type;
56
      typedef _Compare				    key_compare;
57
      typedef _Compare				    value_compare;
58
      typedef _Allocator			    allocator_type;
59
      typedef typename _Base::reference             reference;
60
      typedef typename _Base::const_reference       const_reference;
61
 
62
      typedef __gnu_debug::_Safe_iterator<_Base_iterator, set>
63
                                                    iterator;
64
      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, set>
65
                                                    const_iterator;
66
 
67
      typedef typename _Base::size_type             size_type;
68
      typedef typename _Base::difference_type       difference_type;
69
      typedef typename _Base::pointer               pointer;
70
      typedef typename _Base::const_pointer         const_pointer;
71
      typedef std::reverse_iterator       reverse_iterator;
72
      typedef std::reverse_iterator const_reverse_iterator;
73
 
74
      // 23.3.3.1 construct/copy/destroy:
75
      explicit set(const _Compare& __comp = _Compare(),
76
		   const _Allocator& __a = _Allocator())
77
      : _Base(__comp, __a) { }
78
 
79
      template
80
        set(_InputIterator __first, _InputIterator __last,
81
	    const _Compare& __comp = _Compare(),
82
	    const _Allocator& __a = _Allocator())
83
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
84
								     __last)),
85
		__gnu_debug::__base(__last),
86
		__comp, __a) { }
87
 
88
      set(const set& __x)
89
      : _Base(__x) { }
90
 
91
      set(const _Base& __x)
92
      : _Base(__x) { }
93
 
94
#if __cplusplus >= 201103L
95
      set(set&& __x)
96
      noexcept(is_nothrow_copy_constructible<_Compare>::value)
97
      : _Base(std::move(__x))
98
      { this->_M_swap(__x); }
99
 
100
      set(initializer_list __l,
101
	  const _Compare& __comp = _Compare(),
102
	  const allocator_type& __a = allocator_type())
103
      : _Base(__l, __comp, __a) { }
104
#endif
105
 
106
      ~set() _GLIBCXX_NOEXCEPT { }
107
 
108
      set&
109
      operator=(const set& __x)
110
      {
111
	*static_cast<_Base*>(this) = __x;
112
	this->_M_invalidate_all();
113
	return *this;
114
      }
115
 
116
#if __cplusplus >= 201103L
117
      set&
118
      operator=(set&& __x)
119
      {
120
	// NB: DR 1204.
121
	// NB: DR 675.
122
	__glibcxx_check_self_move_assign(__x);
123
	clear();
124
	swap(__x);
125
	return *this;
126
      }
127
 
128
      set&
129
      operator=(initializer_list __l)
130
      {
131
	this->clear();
132
	this->insert(__l);
133
	return *this;
134
      }
135
#endif
136
 
137
      using _Base::get_allocator;
138
 
139
      // iterators:
140
      iterator
141
      begin() _GLIBCXX_NOEXCEPT
142
      { return iterator(_Base::begin(), this); }
143
 
144
      const_iterator
145
      begin() const _GLIBCXX_NOEXCEPT
146
      { return const_iterator(_Base::begin(), this); }
147
 
148
      iterator
149
      end() _GLIBCXX_NOEXCEPT
150
      { return iterator(_Base::end(), this); }
151
 
152
      const_iterator
153
      end() const _GLIBCXX_NOEXCEPT
154
      { return const_iterator(_Base::end(), this); }
155
 
156
      reverse_iterator
157
      rbegin() _GLIBCXX_NOEXCEPT
158
      { return reverse_iterator(end()); }
159
 
160
      const_reverse_iterator
161
      rbegin() const _GLIBCXX_NOEXCEPT
162
      { return const_reverse_iterator(end()); }
163
 
164
      reverse_iterator
165
      rend() _GLIBCXX_NOEXCEPT
166
      { return reverse_iterator(begin()); }
167
 
168
      const_reverse_iterator
169
      rend() const _GLIBCXX_NOEXCEPT
170
      { return const_reverse_iterator(begin()); }
171
 
172
#if __cplusplus >= 201103L
173
      const_iterator
174
      cbegin() const noexcept
175
      { return const_iterator(_Base::begin(), this); }
176
 
177
      const_iterator
178
      cend() const noexcept
179
      { return const_iterator(_Base::end(), this); }
180
 
181
      const_reverse_iterator
182
      crbegin() const noexcept
183
      { return const_reverse_iterator(end()); }
184
 
185
      const_reverse_iterator
186
      crend() const noexcept
187
      { return const_reverse_iterator(begin()); }
188
#endif
189
 
190
      // capacity:
191
      using _Base::empty;
192
      using _Base::size;
193
      using _Base::max_size;
194
 
195
      // modifiers:
196
#if __cplusplus >= 201103L
197
      template
198
	std::pair
199
	emplace(_Args&&... __args)
200
	{
201
	  auto __res = _Base::emplace(std::forward<_Args>(__args)...);
202
	  return std::pair(iterator(__res.first, this),
203
					   __res.second);
204
	}
205
 
206
      template
207
	iterator
208
	emplace_hint(const_iterator __pos, _Args&&... __args)
209
	{
210
	  __glibcxx_check_insert(__pos);
211
	  return iterator(_Base::emplace_hint(__pos.base(),
212
					      std::forward<_Args>(__args)...),
213
			  this);
214
	}
215
#endif
216
 
217
      std::pair
218
      insert(const value_type& __x)
219
      {
220
	std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
221
	return std::pair(iterator(__res.first, this),
222
					 __res.second);
223
      }
224
 
225
#if __cplusplus >= 201103L
226
      std::pair
227
      insert(value_type&& __x)
228
      {
229
	std::pair<_Base_iterator, bool> __res
230
	  = _Base::insert(std::move(__x));
231
	return std::pair(iterator(__res.first, this),
232
					 __res.second);
233
      }
234
#endif
235
 
236
      iterator
237
      insert(const_iterator __position, const value_type& __x)
238
      {
239
	__glibcxx_check_insert(__position);
240
	return iterator(_Base::insert(__position.base(), __x), this);
241
      }
242
 
243
#if __cplusplus >= 201103L
244
      iterator
245
      insert(const_iterator __position, value_type&& __x)
246
      {
247
	__glibcxx_check_insert(__position);
248
	return iterator(_Base::insert(__position.base(), std::move(__x)),
249
			this);
250
      }
251
#endif
252
 
253
      template 
254
        void
255
        insert(_InputIterator __first, _InputIterator __last)
256
        {
257
	  __glibcxx_check_valid_range(__first, __last);
258
	  _Base::insert(__gnu_debug::__base(__first),
259
			__gnu_debug::__base(__last));
260
	}
261
 
262
#if __cplusplus >= 201103L
263
      void
264
      insert(initializer_list __l)
265
      { _Base::insert(__l); }
266
#endif
267
 
268
#if __cplusplus >= 201103L
269
      iterator
270
      erase(const_iterator __position)
271
      {
272
	__glibcxx_check_erase(__position);
273
	this->_M_invalidate_if(_Equal(__position.base()));
274
	return iterator(_Base::erase(__position.base()), this);
275
      }
276
#else
277
      void
278
      erase(iterator __position)
279
      {
280
	__glibcxx_check_erase(__position);
281
	this->_M_invalidate_if(_Equal(__position.base()));
282
	_Base::erase(__position.base());
283
      }
284
#endif
285
 
286
      size_type
287
      erase(const key_type& __x)
288
      {
289
	_Base_iterator __victim = _Base::find(__x);
290
	if (__victim == _Base::end())
291
          return 0;
292
	else
293
	  {
294
	    this->_M_invalidate_if(_Equal(__victim));
295
	    _Base::erase(__victim);
296
	    return 1;
297
	  }
298
      }
299
 
300
#if __cplusplus >= 201103L
301
      iterator
302
      erase(const_iterator __first, const_iterator __last)
303
      {
304
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
305
	// 151. can't currently clear() empty container
306
	__glibcxx_check_erase_range(__first, __last);
307
	for (_Base_const_iterator __victim = __first.base();
308
	     __victim != __last.base(); ++__victim)
309
	  {
310
	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
311
				  _M_message(__gnu_debug::__msg_valid_range)
312
				  ._M_iterator(__first, "first")
313
				  ._M_iterator(__last, "last"));
314
	    this->_M_invalidate_if(_Equal(__victim));
315
	  }
316
	return iterator(_Base::erase(__first.base(), __last.base()), this);
317
      }
318
#else
319
      void
320
      erase(iterator __first, iterator __last)
321
      {
322
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
323
	// 151. can't currently clear() empty container
324
	__glibcxx_check_erase_range(__first, __last);
325
	for (_Base_iterator __victim = __first.base();
326
	     __victim != __last.base(); ++__victim)
327
	  {
328
	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
329
				  _M_message(__gnu_debug::__msg_valid_range)
330
				  ._M_iterator(__first, "first")
331
				  ._M_iterator(__last, "last"));
332
	    this->_M_invalidate_if(_Equal(__victim));
333
	  }
334
	_Base::erase(__first.base(), __last.base());
335
      }
336
#endif
337
 
338
      void
339
      swap(set& __x)
340
      {
341
	_Base::swap(__x);
342
	this->_M_swap(__x);
343
      }
344
 
345
      void
346
      clear() _GLIBCXX_NOEXCEPT
347
      {
348
	this->_M_invalidate_all();
349
	_Base::clear();
350
      }
351
 
352
      // observers:
353
      using _Base::key_comp;
354
      using _Base::value_comp;
355
 
356
      // set operations:
357
      iterator
358
      find(const key_type& __x)
359
      { return iterator(_Base::find(__x), this); }
360
 
361
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
362
      // 214. set::find() missing const overload
363
      const_iterator
364
      find(const key_type& __x) const
365
      { return const_iterator(_Base::find(__x), this); }
366
 
367
      using _Base::count;
368
 
369
      iterator
370
      lower_bound(const key_type& __x)
371
      { return iterator(_Base::lower_bound(__x), this); }
372
 
373
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
374
      // 214. set::find() missing const overload
375
      const_iterator
376
      lower_bound(const key_type& __x) const
377
      { return const_iterator(_Base::lower_bound(__x), this); }
378
 
379
      iterator
380
      upper_bound(const key_type& __x)
381
      { return iterator(_Base::upper_bound(__x), this); }
382
 
383
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
384
      // 214. set::find() missing const overload
385
      const_iterator
386
      upper_bound(const key_type& __x) const
387
      { return const_iterator(_Base::upper_bound(__x), this); }
388
 
389
      std::pair
390
      equal_range(const key_type& __x)
391
      {
392
	std::pair<_Base_iterator, _Base_iterator> __res =
393
        _Base::equal_range(__x);
394
	return std::make_pair(iterator(__res.first, this),
395
			      iterator(__res.second, this));
396
      }
397
 
398
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
399
      // 214. set::find() missing const overload
400
      std::pair
401
      equal_range(const key_type& __x) const
402
      {
403
	std::pair<_Base_iterator, _Base_iterator> __res =
404
        _Base::equal_range(__x);
405
	return std::make_pair(const_iterator(__res.first, this),
406
			      const_iterator(__res.second, this));
407
      }
408
 
409
      _Base&
410
      _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
411
 
412
      const _Base&
413
      _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
414
 
415
    private:
416
      void
417
      _M_invalidate_all()
418
      {
419
	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
420
	this->_M_invalidate_if(_Not_equal(_M_base().end()));
421
      }
422
    };
423
 
424
  template
425
    inline bool
426
    operator==(const set<_Key, _Compare, _Allocator>& __lhs,
427
	       const set<_Key, _Compare, _Allocator>& __rhs)
428
    { return __lhs._M_base() == __rhs._M_base(); }
429
 
430
  template
431
    inline bool
432
    operator!=(const set<_Key, _Compare, _Allocator>& __lhs,
433
	       const set<_Key, _Compare, _Allocator>& __rhs)
434
    { return __lhs._M_base() != __rhs._M_base(); }
435
 
436
  template
437
    inline bool
438
    operator<(const set<_Key, _Compare, _Allocator>& __lhs,
439
	      const set<_Key, _Compare, _Allocator>& __rhs)
440
    { return __lhs._M_base() < __rhs._M_base(); }
441
 
442
  template
443
    inline bool
444
    operator<=(const set<_Key, _Compare, _Allocator>& __lhs,
445
	       const set<_Key, _Compare, _Allocator>& __rhs)
446
    { return __lhs._M_base() <= __rhs._M_base(); }
447
 
448
  template
449
    inline bool
450
    operator>=(const set<_Key, _Compare, _Allocator>& __lhs,
451
	       const set<_Key, _Compare, _Allocator>& __rhs)
452
    { return __lhs._M_base() >= __rhs._M_base(); }
453
 
454
  template
455
    inline bool
456
    operator>(const set<_Key, _Compare, _Allocator>& __lhs,
457
	      const set<_Key, _Compare, _Allocator>& __rhs)
458
    { return __lhs._M_base() > __rhs._M_base(); }
459
 
460
  template
461
    void
462
    swap(set<_Key, _Compare, _Allocator>& __x,
463
	 set<_Key, _Compare, _Allocator>& __y)
464
    { return __x.swap(__y); }
465
 
466
} // namespace __debug
467
} // namespace std
468
 
469
#endif