Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/gen/degenerate_map.h

Go to the documentation of this file.
00001 //  Copyright (C) 2000--2002  Petter Urkedal
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: degenerate_map.h,v 1.2 2002/08/24 13:57:08 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_GEN_DEGENERATE_MAP_H
00031 #define MORE_GEN_DEGENERATE_MAP_H
00032 
00033 
00034 #include <more/gen/utility.h>
00035 #include <functional>
00036 #include <more/gen/iterator.h>
00037 #include <set>
00038 
00039 
00040 namespace more {
00041 namespace gen {
00042 
00043   /** \class degenerate_map degenerate_map.h more/gen/degenerate_map.h
00044    ** A map with degenerate values.  The degeneracy of an element is
00045    ** defined as the number of insertions minus the number of erases
00046    ** of the element or keys which is equal to its key according to
00047    ** the given comparison functional. */
00048   template< typename Key, typename Data,
00049             typename Compare = std::less<Key> >
00050     struct degenerate_map
00051     {
00052 
00053         typedef Key key_type;
00054         typedef Data mapped_type;
00055         typedef std::pair<const key_type, mapped_type> value_type;
00056         typedef Compare key_compare;
00057         typedef std::size_t size_type;
00058 
00059     private:
00060         class selector;
00061         class sub_key_compare;
00062 
00063         struct value_compare
00064             : std::binary_function<value_type, value_type, bool>
00065         {
00066             value_compare() {}
00067 
00068             value_compare(key_compare const& keycomp_)
00069                 : keycomp(keycomp_) {}
00070 
00071             value_compare(value_compare const& vcomp)
00072                 : keycomp(vcomp.keycomp) {}
00073 
00074             bool operator()(value_type const& x, value_type const& y) const
00075             {
00076                 return key_compare()(x.first, y.first);
00077             }
00078 
00079           private:
00080             key_compare keycomp;
00081         };
00082 
00083         struct sub_value_type
00084         {
00085             explicit sub_value_type(key_type const& k)
00086                 : value(k, mapped_type()) {}
00087             sub_value_type(value_type const& val, size_type deg)
00088                 : value(val), degeneracy(deg) {}
00089             sub_value_type(sub_value_type const& sub)
00090                 : value(sub.value), degeneracy(sub.degeneracy) {}
00091 
00092             sub_value_type& operator=(sub_value_type const& sub)
00093             {
00094                 const_cast<key_type&>(value.first) = sub.value.first;
00095                 value.second = sub.value.second;
00096                 degeneracy = sub.degeneracy;
00097                 return *this;
00098             }
00099 
00100             bool operator==(sub_value_type const& rhs) const
00101             {
00102                 return degeneracy == rhs.degeneracy
00103                     && value == rhs.value;
00104             }
00105 
00106             bool operator!=(sub_value_type const& rhs) const
00107             {
00108                 return degeneracy != rhs.degeneracy
00109                     || value != rhs.value;
00110             }
00111 
00112             bool operator<(sub_value_type const& rhs) const
00113             {
00114                 return value < rhs.value
00115                     || (value == rhs.value && degeneracy < rhs.degeneracy);
00116             }
00117 
00118           private:
00119             mutable value_type value;
00120 //          mutable std::pair<key_type, mapped_type> value;
00121             mutable size_type degeneracy;
00122             friend class degenerate_map;
00123             friend class selector;
00124             friend class sub_key_compare;
00125         };
00126 
00127         struct sub_key_compare
00128         {
00129             sub_key_compare() {}
00130             sub_key_compare(sub_key_compare const& comp)
00131                 : subcomp(comp.subcomp) {}
00132             sub_key_compare(key_compare const& kc)
00133                 : subcomp(kc) {}
00134 
00135             bool operator()(sub_value_type const& x,
00136                             sub_value_type const& y) const
00137             {
00138                 return subcomp(x.value.first, y.value.first);
00139             }
00140 
00141           private:
00142             key_compare subcomp;
00143         };
00144 
00145         typedef std::set<sub_value_type, sub_key_compare> container;
00146         typedef typename container::iterator sub_iterator;
00147         typedef typename container::reverse_iterator
00148                 reverse_sub_iterator;
00149 
00150         struct selector : std::unary_function<sub_value_type, value_type>
00151         {
00152             value_type& operator()(sub_value_type const& x) const
00153             {
00154                 return x.value;
00155             }
00156         };
00157 
00158     public:
00159         typedef transforming_iterator<sub_iterator, selector>
00160                 const_iterator;
00161         typedef transforming_iterator<reverse_sub_iterator, selector>
00162                 const_reverse_iterator;
00163         typedef const_iterator iterator;
00164         typedef const_reverse_iterator reverse_iterator;
00165         typedef value_type& reference;
00166         typedef const value_type& const_reference;
00167         typedef value_type* pointer;
00168         typedef typename container::difference_type difference_type;
00169         typedef typename container::size_type size_type;
00170 
00171         degenerate_map() {}
00172         degenerate_map(degenerate_map const& x)
00173             : S(x.S) {}
00174         degenerate_map(key_compare const& comp)
00175             : S(sub_key_compare(comp)) {}
00176         degenerate_map& operator=(degenerate_map const& rhs) {
00177             S = rhs.S;
00178             return *this;
00179         }
00180 
00181 //      template<typename InputIterator>
00182 //        degenerate_map(InputIterator it, InputIterator it_end)
00183 //          { insert(it, it_end); }
00184 
00185         bool operator==(degenerate_map const& rhs) const { return S == rhs.S; }
00186         bool operator!=(degenerate_map const& rhs) const { return S != rhs.S; }
00187         bool operator<(degenerate_map const& rhs) const { return S < rhs.S; }
00188         bool operator<=(degenerate_map const& rhs) const { return S <= rhs.S; }
00189         bool operator>(degenerate_map const& rhs) const { return S > rhs.S; }
00190         bool operator>=(degenerate_map const& rhs) const { return S >= rhs.S; }
00191 
00192         iterator begin() const { return iterator(S.begin()); }
00193         iterator end() const { return iterator(S.end()); }
00194         reverse_iterator rbegin() const
00195             { return reverse_iterator(S.rbegin()); }
00196         reverse_iterator rend() const
00197             { return reverse_iterator(S.rend()); }
00198 
00199         size_type size() const { return S.size(); }
00200         size_type max_size() const { return S.max_size(); }
00201         size_type empty() const { return S.empty(); }
00202         key_compare key_comp() const { return S.key_comp().subcomp; }
00203         value_compare value_comp() const { return S.key_comp().subcomp; }
00204         void swap(degenerate_map& x) { S.swap(x.S); }
00205 
00206         /** Insert \c x into the set. \return A pair of the iterator
00207          ** to the value, and the degeneracy of the value before the
00208          ** insertion. */
00209         std::pair<iterator, size_type>
00210         insert(const value_type& x)
00211         {
00212             sub_iterator it = S.find(sub_value_type(x.first));
00213             if (it == S.end()) {
00214                 std::pair<sub_iterator, bool> p
00215                     = S.insert(sub_value_type(x, 1));
00216                 return std::make_pair(iterator(p.first), 0);
00217             } else
00218                 return std::make_pair(iterator(it), it->degeneracy++);
00219         }
00220 
00221         /** Insert with hint. */
00222         std::pair<iterator, bool>
00223         insert(iterator hint, const value_type& x)
00224         {
00225             return insert(x);
00226         }
00227 
00228         /** Increase the degneracy of \c it. \pre \c it must be a
00229          ** valid iterator pointing into this container. */
00230         std::pair<iterator, size_type>
00231         insert(iterator it)
00232         {
00233             return std::make_pair(it, it.sub_iterator()->degeneracy++);
00234         }
00235 
00236 //      template<typename InputIterator>
00237 //      void insert(InputIterator it, InputIterator it_end) {
00238 //          while (it != it_end) { insert(*it); ++it; }
00239 //      }
00240 
00241         /** Decrease the degeneracy of \c it, and remove if zero. \pre
00242          ** it must be a valid iterator in this container. */
00243         void erase(iterator it)
00244         {
00245             sub_iterator it0 = it.sub_iterator();
00246             if (--(*it0).degeneracy <= 0) S.erase(it0);
00247         }
00248 
00249         /** Erase a range of iterators. */
00250         void erase(iterator it, iterator it_end)
00251         {
00252             while (it != it_end) {
00253                 erase(it);
00254                 ++it;
00255             }
00256         }
00257 
00258         /** Sink the degeneracy of \c k, and remove if zero. */
00259         size_type erase(key_type const& k)
00260         {
00261             iterator it = find(k);
00262             if (it == end())
00263                 return 0;
00264             else {
00265                 erase(it);
00266                 return 1;
00267             }
00268         }
00269 
00270         iterator find(key_type const& k) const
00271         {
00272             sub_iterator it = S.find(sub_value_type(k));
00273             return iterator(it);
00274         }
00275 
00276         size_type count(key_type const& k) const { return S.count(k); }
00277 
00278         size_type degeneracy(iterator it) const
00279         {
00280             return (*it.sub_iterator()).degeneracy;
00281         }
00282 
00283         size_type degeneracy(key_type const& k) const
00284         {
00285             sub_iterator it = S.find(sub_value_type(k));
00286             if (it == S.end())
00287                 return 0;
00288             else
00289                 return (*it).degeneracy;
00290         }
00291 
00292         iterator lower_bound(const key_type& k) const
00293         {
00294             return iterator(S.lower_bound(k));
00295         }
00296 
00297         iterator upper_bound(const key_type& k) const
00298         {
00299             return iterator(S.upper_bound(k));
00300         }
00301 
00302         std::pair<iterator, iterator>
00303         equal_range(key_type const& k) const
00304         {
00305             std::pair<sub_iterator, sub_iterator> p = S.equal_range(k);
00306             return std::make_pair(iterator(p.first), iterator(p.second));
00307         }
00308 
00309       private:
00310         mutable container S;
00311     };
00312 }} // more::gen
00313 
00314 #endif

Generated on Sat Sep 7 19:11:11 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.