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::__check_valid_range(__first, __last), __last,
00086 __comp, __a) { }
00087
00088 multimap(const multimap& __x)
00089 : _Base(__x), _Safe_base() { }
00090
00091 multimap(const _Base& __x)
00092 : _Base(__x), _Safe_base() { }
00093
00094 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00095 multimap(multimap&& __x)
00096 : _Base(std::forward<multimap>(__x)), _Safe_base()
00097 { this->_M_swap(__x); }
00098
00099 multimap(initializer_list<value_type> __l,
00100 const _Compare& __c = _Compare(),
00101 const allocator_type& __a = allocator_type())
00102 : _Base(__l, __c, __a), _Safe_base() { }
00103 #endif
00104
00105 ~multimap() { }
00106
00107 multimap&
00108 operator=(const multimap& __x)
00109 {
00110 *static_cast<_Base*>(this) = __x;
00111 this->_M_invalidate_all();
00112 return *this;
00113 }
00114
00115 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00116 multimap&
00117 operator=(multimap&& __x)
00118 {
00119
00120
00121 clear();
00122 swap(__x);
00123 return *this;
00124 }
00125
00126 multimap&
00127 operator=(initializer_list<value_type> __l)
00128 {
00129 this->clear();
00130 this->insert(__l);
00131 return *this;
00132 }
00133 #endif
00134
00135 using _Base::get_allocator;
00136
00137
00138 iterator
00139 begin()
00140 { return iterator(_Base::begin(), this); }
00141
00142 const_iterator
00143 begin() const
00144 { return const_iterator(_Base::begin(), this); }
00145
00146 iterator
00147 end()
00148 { return iterator(_Base::end(), this); }
00149
00150 const_iterator
00151 end() const
00152 { return const_iterator(_Base::end(), this); }
00153
00154 reverse_iterator
00155 rbegin()
00156 { return reverse_iterator(end()); }
00157
00158 const_reverse_iterator
00159 rbegin() const
00160 { return const_reverse_iterator(end()); }
00161
00162 reverse_iterator
00163 rend()
00164 { return reverse_iterator(begin()); }
00165
00166 const_reverse_iterator
00167 rend() const
00168 { return const_reverse_iterator(begin()); }
00169
00170 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00171 const_iterator
00172 cbegin() const
00173 { return const_iterator(_Base::begin(), this); }
00174
00175 const_iterator
00176 cend() const
00177 { return const_iterator(_Base::end(), this); }
00178
00179 const_reverse_iterator
00180 crbegin() const
00181 { return const_reverse_iterator(end()); }
00182
00183 const_reverse_iterator
00184 crend() const
00185 { return const_reverse_iterator(begin()); }
00186 #endif
00187
00188
00189 using _Base::empty;
00190 using _Base::size;
00191 using _Base::max_size;
00192
00193
00194 iterator
00195 insert(const value_type& __x)
00196 { return iterator(_Base::insert(__x), this); }
00197
00198 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00199 void
00200 insert(std::initializer_list<value_type> __list)
00201 { _Base::insert(__list); }
00202 #endif
00203
00204 iterator
00205 insert(iterator __position, const value_type& __x)
00206 {
00207 __glibcxx_check_insert(__position);
00208 return iterator(_Base::insert(__position.base(), __x), this);
00209 }
00210
00211 template<typename _InputIterator>
00212 void
00213 insert(_InputIterator __first, _InputIterator __last)
00214 {
00215 __glibcxx_check_valid_range(__first, __last);
00216 _Base::insert(__first, __last);
00217 }
00218
00219 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00220 iterator
00221 erase(iterator __position)
00222 {
00223 __glibcxx_check_erase(__position);
00224 __position._M_invalidate();
00225 return iterator(_Base::erase(__position.base()), this);
00226 }
00227 #else
00228 void
00229 erase(iterator __position)
00230 {
00231 __glibcxx_check_erase(__position);
00232 __position._M_invalidate();
00233 _Base::erase(__position.base());
00234 }
00235 #endif
00236
00237 size_type
00238 erase(const key_type& __x)
00239 {
00240 std::pair<iterator, iterator> __victims = this->equal_range(__x);
00241 size_type __count = 0;
00242 while (__victims.first != __victims.second)
00243 {
00244 iterator __victim = __victims.first++;
00245 __victim._M_invalidate();
00246 _Base::erase(__victim.base());
00247 ++__count;
00248 }
00249 return __count;
00250 }
00251
00252 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00253 iterator
00254 erase(iterator __first, iterator __last)
00255 {
00256
00257
00258 __glibcxx_check_erase_range(__first, __last);
00259 while (__first != __last)
00260 this->erase(__first++);
00261 return __last;
00262 }
00263 #else
00264 void
00265 erase(iterator __first, iterator __last)
00266 {
00267
00268
00269 __glibcxx_check_erase_range(__first, __last);
00270 while (__first != __last)
00271 this->erase(__first++);
00272 }
00273 #endif
00274
00275 void
00276 swap(multimap& __x)
00277 {
00278 _Base::swap(__x);
00279 this->_M_swap(__x);
00280 }
00281
00282 void
00283 clear()
00284 { this->erase(begin(), end()); }
00285
00286
00287 using _Base::key_comp;
00288 using _Base::value_comp;
00289
00290
00291 iterator
00292 find(const key_type& __x)
00293 { return iterator(_Base::find(__x), this); }
00294
00295 const_iterator
00296 find(const key_type& __x) const
00297 { return const_iterator(_Base::find(__x), this); }
00298
00299 using _Base::count;
00300
00301 iterator
00302 lower_bound(const key_type& __x)
00303 { return iterator(_Base::lower_bound(__x), this); }
00304
00305 const_iterator
00306 lower_bound(const key_type& __x) const
00307 { return const_iterator(_Base::lower_bound(__x), this); }
00308
00309 iterator
00310 upper_bound(const key_type& __x)
00311 { return iterator(_Base::upper_bound(__x), this); }
00312
00313 const_iterator
00314 upper_bound(const key_type& __x) const
00315 { return const_iterator(_Base::upper_bound(__x), this); }
00316
00317 std::pair<iterator,iterator>
00318 equal_range(const key_type& __x)
00319 {
00320 typedef typename _Base::iterator _Base_iterator;
00321 std::pair<_Base_iterator, _Base_iterator> __res =
00322 _Base::equal_range(__x);
00323 return std::make_pair(iterator(__res.first, this),
00324 iterator(__res.second, this));
00325 }
00326
00327 std::pair<const_iterator,const_iterator>
00328 equal_range(const key_type& __x) const
00329 {
00330 typedef typename _Base::const_iterator _Base_const_iterator;
00331 std::pair<_Base_const_iterator, _Base_const_iterator> __res =
00332 _Base::equal_range(__x);
00333 return std::make_pair(const_iterator(__res.first, this),
00334 const_iterator(__res.second, this));
00335 }
00336
00337 _Base&
00338 _M_base() { return *this; }
00339
00340 const _Base&
00341 _M_base() const { return *this; }
00342
00343 private:
00344 void
00345 _M_invalidate_all()
00346 {
00347 typedef typename _Base::const_iterator _Base_const_iterator;
00348 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00349 this->_M_invalidate_if(_Not_equal(_M_base().end()));
00350 }
00351 };
00352
00353 template<typename _Key, typename _Tp,
00354 typename _Compare, typename _Allocator>
00355 inline bool
00356 operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00357 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00358 { return __lhs._M_base() == __rhs._M_base(); }
00359
00360 template<typename _Key, typename _Tp,
00361 typename _Compare, typename _Allocator>
00362 inline bool
00363 operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00364 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00365 { return __lhs._M_base() != __rhs._M_base(); }
00366
00367 template<typename _Key, typename _Tp,
00368 typename _Compare, typename _Allocator>
00369 inline bool
00370 operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00371 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00372 { return __lhs._M_base() < __rhs._M_base(); }
00373
00374 template<typename _Key, typename _Tp,
00375 typename _Compare, typename _Allocator>
00376 inline bool
00377 operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00378 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00379 { return __lhs._M_base() <= __rhs._M_base(); }
00380
00381 template<typename _Key, typename _Tp,
00382 typename _Compare, typename _Allocator>
00383 inline bool
00384 operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00385 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00386 { return __lhs._M_base() >= __rhs._M_base(); }
00387
00388 template<typename _Key, typename _Tp,
00389 typename _Compare, typename _Allocator>
00390 inline bool
00391 operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00392 const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00393 { return __lhs._M_base() > __rhs._M_base(); }
00394
00395 template<typename _Key, typename _Tp,
00396 typename _Compare, typename _Allocator>
00397 inline void
00398 swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00399 multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00400 { __lhs.swap(__rhs); }
00401
00402 }
00403 }
00404
00405 #endif