# safe_association.h

Go to the documentation of this file.

    00001 // Safe associated container base class implementation  -*- C++ -*-
    00002
    00003 // Copyright (C) 2007 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 2, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file debug/safe_association.h
    00031  *  This file is a GNU debug extension to the Standard C++ Library.
    00032  */
    00033
    00034 #ifndef _GLIBCXX_DEBUG_SAFE_ASSOCIATION_H
    00035 #define _GLIBCXX_DEBUG_SAFE_ASSOCIATION_H 1
    00036
    00037 #include <debug/debug.h>
    00038 #include <debug/macros.h>
    00039 #include <debug/functions.h>
    00040 #include <debug/formatter.h>
    00041 #include <debug/safe_sequence.h>
    00042
    00043 namespace __gnu_debug
    00044 {
    00045   /**
    00046    * @brief Base class for constructing a "safe" associated container type.
    00047    *
    00048    * The class template %_Safe_association simplifies the construction of
    00049    * "safe" associated containers.
    00050    */
    00051   template<typename _Base>
    00052     class _Safe_association
    00053     : public _Base
    00054     {
    00055     public:
    00056       typedef typename _Base::size_type       size_type;
    00057       typedef typename _Base::hasher          hasher;
    00058       typedef typename _Base::key_equal       key_equal;
    00059       typedef typename _Base::allocator_type allocator_type;
    00060
    00061       typedef typename _Base::key_type        key_type;
    00062       typedef typename _Base::value_type      value_type;
    00063       typedef typename _Base::difference_type difference_type;
    00064       typedef typename _Base::reference       reference;
    00065       typedef typename _Base::const_reference const_reference;
    00066
    00067       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
    00068                       _Safe_association>
    00069                                               iterator;
    00070       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
    00071                       _Safe_association>
    00072                                               const_iterator;
    00073
    00074       _Safe_association() { }
    00075
    00076       explicit _Safe_association(size_type __n) : _Base(__n) { }
    00077
    00078       _Safe_association(size_type __n, const hasher& __hf)
    00079       : _Base(__n, __hf) { }
    00080
    00081       _Safe_association(size_type __n, const hasher& __hf,
    00082             const key_equal& __eql,
    00083             const allocator_type& __a = allocator_type())
    00084       : _Base(__n, __hf, __eql, __a) { }
    00085
    00086       template<typename _InputIter>
    00087         _Safe_association(_InputIter __f, _InputIter __l)
    00088     : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { }
    00089
    00090       template<typename _InputIter>
    00091         _Safe_association(_InputIter __f, _InputIter __l, size_type __n)
    00092     : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { }
    00093
    00094       template<typename _InputIter>
    00095         _Safe_association(_InputIter __f, _InputIter __l, size_type __n,
    00096               const hasher& __hf)
    00097     : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf)
    00098         { }
    00099
    00100       template<typename _InputIter>
    00101         _Safe_association(_InputIter __f, _InputIter __l, size_type __n,
    00102               const hasher& __hf, const key_equal& __eql,
    00103               const allocator_type& __a = allocator_type())
    00104     : _Base(__gnu_debug::__check_valid_range(__f, __l),
    00105         __l, __n, __hf, __eql, __a)
    00106         { }
    00107
    00108       _Safe_association(const _Base& __x) : _Base(__x) { }
    00109
    00110       _Safe_association(_Safe_association&& __x)
    00111       : _Base(std::forward<_Base>(__x)) { }
    00112
    00113       using _Base::size;
    00114       using _Base::max_size;
    00115       using _Base::empty;
    00116       using _Base::get_allocator;
    00117       using _Base::key_eq;
    00118
    00119       using _Base::count;
    00120       using _Base::bucket_count;
    00121       using _Base::max_bucket_count;
    00122       using _Base::bucket;
    00123       using _Base::bucket_size;
    00124       using _Base::load_factor;
    00125
    00126       const_iterator
    00127       begin() const { return const_iterator(_Base::begin(), this); }
    00128
    00129       const_iterator
    00130       end() const   { return const_iterator(_Base::end(), this); }
    00131
    00132       std::pair<iterator, bool>
    00133       insert(const value_type& __obj)
    00134       {
    00135     typedef std::pair<typename _Base::iterator, bool> __pair_type;
    00136     __pair_type __res = _Base::insert(__obj);
    00137     return std::make_pair(iterator(__res.first, this), __res.second);
    00138       }
    00139
    00140       void
    00141       insert(const value_type* __first, const value_type* __last)
    00142       {
    00143     __glibcxx_check_valid_range(__first, __last);
    00144     _Base::insert(__first, __last);
    00145       }
    00146
    00147       template<typename _InputIter>
    00148         void
    00149         insert(_InputIter __first, _InputIter __last)
    00150         {
    00151       __glibcxx_check_valid_range(__first, __last);
    00152       _Base::insert(__first.base(), __last.base());
    00153     }
    00154
    00155       const_iterator
    00156       find(const key_type& __key) const
    00157       { return const_iterator(_Base::find(__key), this); }
    00158
    00159       std::pair<const_iterator, const_iterator>
    00160       equal_range(const key_type& __key) const
    00161       {
    00162     typedef typename _Base::const_iterator _Base_iterator;
    00163     typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
    00164     __pair_type __res = _Base::equal_range(__key);
    00165     return std::make_pair(const_iterator(__res.first, this),
    00166                   const_iterator(__res.second, this));
    00167       }
    00168
    00169       size_type
    00170       erase(const key_type& __key)
    00171       {
    00172     size_type __ret(0);
    00173     iterator __victim(_Base::find(__key), this);
    00174     if (__victim != end())
    00175       {
    00176         this->erase(__victim);
    00177         __ret = 1;
    00178       }
    00179     return __ret;
    00180       }
    00181
    00182       iterator
    00183       erase(iterator __it)
    00184       {
    00185     __glibcxx_check_erase(__it);
    00186     __it._M_invalidate();
    00187     return iterator(_Base::erase(__it.base()));
    00188       }
    00189
    00190       iterator
    00191       erase(iterator __first, iterator __last)
    00192       {
    00193     __glibcxx_check_erase_range(__first, __last);
    00194     for (iterator __tmp = __first; __tmp != __last;)
    00195     {
    00196       iterator __victim = __tmp++;
    00197       __victim._M_invalidate();
    00198     }
    00199     return iterator(_Base::erase(__first.base(), __last.base()));
    00200       }
    00201
    00202       _Base&
    00203       _M_base() { return *this; }
    00204
    00205       const _Base&
    00206       _M_base() const { return *this; }
    00207     };
    00208 } // namespace __gnu_debug
    00209
    00210 #endif