Import pre-release gcc-5.0 to new vendor branch
[dragonfly.git] / contrib / gcc-5.0 / libstdc++-v3 / include / debug / multimap.h
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 // <http://www.gnu.org/licenses/>.
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 <debug/safe_sequence.h>
33 #include <debug/safe_container.h>
34 #include <debug/safe_iterator.h>
35 #include <utility>
36
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 namespace __debug
40 {
41   /// Class std::multimap with safety/checking/debug instrumentation.
42   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
43            typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
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<const _Key, _Tp>                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<iterator>           reverse_iterator;
79       typedef std::reverse_iterator<const_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<value_type> __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<value_type> __l, const allocator_type& __a)
112       : _Base(__l, __a) { }
113
114       template<typename _InputIterator>
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<typename _InputIterator>
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<value_type> __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<typename... _Args>
225         iterator
226         emplace(_Args&&... __args)
227         {
228           return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
229         }
230
231       template<typename... _Args>
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<typename _Pair, typename = typename
248                std::enable_if<std::is_constructible<value_type,
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<value_type> __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<typename _Pair, typename = typename
274                std::enable_if<std::is_constructible<value_type,
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<typename _InputIterator>
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<iterator,iterator>
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<const_iterator,const_iterator>
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<typename _Key, typename _Tp,
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<typename _Key, typename _Tp,
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<typename _Key, typename _Tp,
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<typename _Key, typename _Tp,
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<typename _Key, typename _Tp,
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<typename _Key, typename _Tp,
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<typename _Key, typename _Tp,
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