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