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