Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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