00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
00031 #define _GLIBCXX_DEBUG_MULTIMAP_H 1
00032
00033 #include <debug/safe_sequence.h>
00034 #include <debug/safe_iterator.h>
00035 #include <utility>
00036
00037 namespace std
00038 {
00039 namespace __debug
00040 {
00041
00042 template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
00043 typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
00044 class multimap
00045 : public _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator>,
00046 public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp,
00047 _Compare, _Allocator> >
00048 {
00049 typedef _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
00050 typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
00051
00052 public:
00053
00054 typedef _Key key_type;
00055 typedef _Tp mapped_type;
00056 typedef std::pair<const _Key, _Tp> value_type;
00057 typedef _Compare key_compare;
00058 typedef _Allocator allocator_type;
00059 typedef typename _Base::reference reference;
00060 typedef typename _Base::const_reference const_reference;
00061
00062 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap>
00063 iterator;
00064 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
00065 multimap> const_iterator;
00066
00067 typedef typename _Base::size_type size_type;
00068 typedef typename _Base::difference_type difference_type;
00069 typedef typename _Base::pointer pointer;
00070 typedef typename _Base::const_pointer const_pointer;
00071 typedef std::reverse_iterator<iterator> reverse_iterator;
00072 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00073
00074 using _Base::value_compare;
00075
00076
00077 explicit multimap(const _Compare& __comp = _Compare(),
00078 const _Allocator& __a = _Allocator())
00079 : _Base(__comp, __a) { }
00080
00081 template<typename _InputIterator>
00082 multimap(_InputIterator __first, _InputIterator __last,
00083 const _Compare& __comp = _Compare(),
00084 const _Allocator& __a = _Allocator())
00085 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00086 __last)),
00087 __gnu_debug::__base(__last),
00088 __comp, __a) { }
00089
00090 multimap(const multimap& __x)
00091 : _Base(__x), _Safe_base() { }
00092
00093 multimap(const _Base& __x)
00094 : _Base(__x), _Safe_base() { }
00095
00096 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00097 multimap(multimap&& __x)
00098 : _Base(std::move(__x)), _Safe_base()
00099 { this->_M_swap(__x); }
00100
00101 multimap(initializer_list<value_type> __l,
00102 const _Compare& __c = _Compare(),
00103 const allocator_type& __a = allocator_type())
00104 : _Base(__l, __c, __a), _Safe_base() { }
00105 #endif
00106
00107 ~multimap() { }
00108
00109 multimap&
00110 operator=(const multimap& __x)
00111 {
00112 *static_cast<_Base*>(this) = __x;
00113 this->_M_invalidate_all();
00114 return *this;
00115 }
00116
00117 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00118 multimap&
00119 operator=(multimap&& __x)
00120 {
00121
00122
00123 clear();
00124 swap(__x);
00125 return *this;
00126 }
00127
00128 multimap&
00129 operator=(initializer_list<value_type> __l)
00130 {
00131 this->clear();
00132 this->insert(__l);
00133 return *this;
00134 }
00135 #endif
00136
00137 using _Base::get_allocator;
00138
00139
00140 iterator
00141 begin()
00142 { return iterator(_Base::begin(), this); }
00143
00144 const_iterator
00145 begin() const
00146 { return const_iterator(_Base::begin(), this); }
00147
00148 iterator
00149 end()
00150 { return iterator(_Base::end(), this); }
00151
00152 const_iterator
00153 end() const
00154 { return const_iterator(_Base::end(), this); }
00155
00156 reverse_iterator
00157 rbegin()
00158 { return reverse_iterator(end()); }
00159
00160 const_reverse_iterator
00161 rbegin() const
00162 { return const_reverse_iterator(end()); }
00163
00164 reverse_iterator
00165 rend()
00166 { return reverse_iterator(begin()); }
00167
00168 const_reverse_iterator
00169 rend() const
00170 { return const_reverse_iterator(begin()); }
00171
00172 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00173 const_iterator
00174 cbegin() const
00175 { return const_iterator(_Base::begin(), this); }
00176
00177 const_iterator
00178 cend() const
00179 { return const_iterator(_Base::end(), this); }
00180
00181 const_reverse_iterator
00182 crbegin() const
00183 { return const_reverse_iterator(end()); }
00184
00185 const_reverse_iterator
00186 crend() const
00187 { return const_reverse_iterator(begin()); }
00188 #endif
00189
00190
00191 using _Base::empty;
00192 using _Base::size;
00193 using _Base::max_size;
00194
00195
00196 iterator
00197 insert(const value_type& __x)
00198 { return iterator(_Base::insert(__x), this); }
00199
00200 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00201 void
00202 insert(std::initializer_list<value_type> __list)
00203 { _Base::insert(__list); }
00204 #endif
00205
00206 iterator
00207 insert(iterator __position, const value_type& __x)
00208 {
00209 __glibcxx_check_insert(__position);
00210 return iterator(_Base::insert(__position.base(), __x), this);
00211 }
00212
00213 template<typename _InputIterator>
00214 void
00215 insert(_InputIterator __first, _InputIterator __last)
00216 {
00217 __glibcxx_check_valid_range(__first, __last);
00218 _Base::insert(__gnu_debug::__base(__first),
00219 __gnu_debug::__base(__last));
00220 }
00221
00222 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00223 iterator
00224 erase(iterator __position)
00225 {
00226 __glibcxx_check_erase(__position);
00227 __position._M_invalidate();
00228 return iterator(_Base::erase(__position.base()), this);
00229 }
00230 #else
00231 void
00232 erase(iterator __position)
00233 {
00234 __glibcxx_check_erase(__position);
00235 __position._M_invalidate();
00236 _Base::erase(__position.base());
00237 }
00238 #endif
00239
00240 size_type
00241 erase(const key_type& __x)
00242 {
00243 std::pair<iterator, iterator> __victims = this->equal_range(__x);
00244 size_type __count = 0;
00245 while (__victims.first != __victims.second)
00246 {
00247 iterator __victim = __victims.first++;
00248 __victim._M_invalidate();
00249 _Base::erase(__victim.base());
00250 ++__count;
00251 }
00252 return __count;
00253 }
00254
00255 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00256 iterator
00257 erase(iterator __first, iterator __last)
00258 {
00259
00260
00261 __glibcxx_check_erase_range(__first, __last);
00262 while (__first != __last)
00263 this->erase(__first++);
00264 return __last;
00265 }
00266 #else
00267 void
00268 erase(iterator __first, iterator __last)
00269 {
00270
00271
00272 __glibcxx_check_erase_range(__first, __last);
00273 while (__first != __last)
00274 this->erase(__first++);
00275 }
00276 #endif
00277
00278 void
00279 swap(multimap& __x)
00280 {
00281 _Base::swap(__x);
00282 this->_M_swap(__x);
00283 }
00284
00285 void
00286 clear()
00287 { this->erase(begin(), end()); }
00288
00289
00290 using _Base::key_comp;
00291 using _Base::value_comp;
00292
00293
00294 iterator
00295 find(const key_type& __x)
00296 { return iterator(_Base::find(__x), this); }
00297
00298 const_iterator
00299 find(const key_type& __x) const
00300 { return const_iterator(_Base::find(__x), this); }
00301
00302 using _Base::count;
00303
00304 iterator
00305 lower_bound(const key_type& __x)
00306 { return iterator(_Base::lower_bound(__x), this); }
00307
00308 const_iterator
00309 lower_bound(const key_type& __x) const
00310 { return const_iterator(_Base::lower_bound(__x), this); }
00311
00312 iterator
00313 upper_bound(const key_type& __x)
00314 { return iterator(_Base::upper_bound(__x), this); }
00315
00316 const_iterator
00317 upper_bound(const key_type& __x) const
00318 { return const_iterator(_Base::upper_bound(__x), this); }
00319
00320 std::pair<iterator,iterator>
00321 equal_range(const key_type& __x)
00322 {
00323 typedef typename _Base::iterator _Base_iterator;
00324 std::pair<_Base_iterator, _Base_iterator> __res =
00325 _Base::equal_range(__x);
00326 return std::make_pair(iterator(__res.first, this),
00327 iterator(__res.second, this));
00328 }
00329
00330 std::pair<const_iterator,const_iterator>
00331 equal_range(const key_type& __x) const
00332 {
00333 typedef typename _Base::const_iterator _Base_const_iterator;
00334 std::pair<_Base_const_iterator, _Base_const_iterator> __res =
00335 _Base::equal_range(__x);
00336 return std::make_pair(const_iterator(__res.first, this),
00337 const_iterator(__res.second, this));
00338 }
00339
00340 _Base&
00341 _M_base() { return *this; }
00342
00343 const _Base&
00344 _M_base() const { return *this; }
00345
00346 private:
00347 void
00348 _M_invalidate_all()
00349 {
00350 typedef typename _Base::const_iterator _Base_const_iterator;
00351 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00352 this->_M_invalidate_if(_Not_equal(_M_base().end()));
00353 }
00354 };
00355
00356 template<typename _Key, typename _Tp,
00357 typename _Compare, typename _Allocator>
00358 inline bool
00359 operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00360 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00361 { return __lhs._M_base() == __rhs._M_base(); }
00362
00363 template<typename _Key, typename _Tp,
00364 typename _Compare, typename _Allocator>
00365 inline bool
00366 operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00367 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00368 { return __lhs._M_base() != __rhs._M_base(); }
00369
00370 template<typename _Key, typename _Tp,
00371 typename _Compare, typename _Allocator>
00372 inline bool
00373 operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00374 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00375 { return __lhs._M_base() < __rhs._M_base(); }
00376
00377 template<typename _Key, typename _Tp,
00378 typename _Compare, typename _Allocator>
00379 inline bool
00380 operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00381 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00382 { return __lhs._M_base() <= __rhs._M_base(); }
00383
00384 template<typename _Key, typename _Tp,
00385 typename _Compare, typename _Allocator>
00386 inline bool
00387 operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00388 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00389 { return __lhs._M_base() >= __rhs._M_base(); }
00390
00391 template<typename _Key, typename _Tp,
00392 typename _Compare, typename _Allocator>
00393 inline bool
00394 operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00395 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00396 { return __lhs._M_base() > __rhs._M_base(); }
00397
00398 template<typename _Key, typename _Tp,
00399 typename _Compare, typename _Allocator>
00400 inline void
00401 swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00402 multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00403 { __lhs.swap(__rhs); }
00404
00405 }
00406 }
00407
00408 #endif