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

more/gen/degenerate_set.h

Go to the documentation of this file.
00001 //  Copyright (C) 2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
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_set.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_GEN_DEGENERATE_SET_H
00031 #define MORE_GEN_DEGENETATE_SET_H
00032 
00033 
00034 #include <more/gen/utility.h>
00035 #include <more/gen/iterator.h>
00036 #include <functional>
00037 #include <set>
00038 
00039 
00040 namespace more {
00041 namespace gen {
00042 
00043   /** \class degenerate_set degenerate_set.h more/gen/degenerate_set.h
00044    ** A set which supports degenerate elements.  The degeneracy of an
00045    ** element is defined as the number of insertions minus the number
00046    ** of erases of the element or values which is equal to it
00047    ** according to the given comparison functional. */
00048   template< typename Key, typename Compare = std::less<Key> >
00049     struct degenerate_set
00050     {
00051         typedef Key key_type;
00052         typedef Key value_type;
00053         typedef Compare key_compare;
00054         typedef Compare value_compare;
00055         typedef std::size_t size_type;
00056 
00057     private:
00058         class selector;
00059         class sub_key_compare;
00060 
00061         struct sub_value_type
00062         {
00063             explicit sub_value_type(key_type const& k)
00064                 : value(k) {}
00065 
00066             sub_value_type(value_type const& val, size_type deg)
00067                 : value(val), degeneracy(deg) {}
00068 
00069             sub_value_type(sub_value_type const& x)
00070                 : value(x.value), degeneracy(x.degeneracy) {}
00071 
00072             sub_value_type& operator=(sub_value_type const& x)
00073             {
00074                 value = x.value;
00075                 degeneracy = x.degeneracy;
00076                 return *this;
00077             }
00078 
00079             bool operator==(sub_value_type const& rhs) const
00080             {
00081                 return degeneracy == rhs.degeneracy
00082                     && value == rhs.value;
00083             }
00084 
00085             bool operator!=(sub_value_type const& rhs) const
00086             {
00087                 return degeneracy != rhs.degeneracy
00088                     || value != rhs.value;
00089             }
00090 
00091             bool operator<(sub_value_type const& rhs) const
00092             {
00093                 return value < rhs.value
00094                     || (value == rhs.value && degeneracy < rhs.degeneracy);
00095             }
00096 
00097           private:
00098             value_type value;
00099             mutable size_type degeneracy;
00100             friend class degenerate_set;
00101             friend class selector;
00102             friend class sub_key_compare;
00103         };
00104 
00105         struct sub_key_compare
00106         {
00107             sub_key_compare() {}
00108             sub_key_compare(sub_key_compare const& comp)
00109                 : subcomp(comp.subcomp) {}
00110             sub_key_compare(key_compare const& kc)
00111                 : subcomp(kc) {}
00112 
00113             bool operator()(sub_value_type const& x,
00114                             sub_value_type const& y) const
00115             {
00116                 return subcomp(x.value, y.value);
00117             }
00118 
00119           private:
00120             key_compare subcomp;
00121         };
00122 
00123         typedef std::set<sub_value_type, sub_key_compare> container;
00124         typedef typename container::iterator sub_iterator;
00125         typedef typename container::reverse_iterator
00126                 reverse_sub_iterator;
00127         struct selector
00128             : std::unary_function<sub_value_type, const value_type>
00129         {
00130             value_type const& operator()(sub_value_type const& x) const
00131             {
00132                 return x.value;
00133             }
00134         };
00135 
00136     public:
00137         typedef transforming_iterator<sub_iterator, selector>
00138                 const_iterator;
00139         typedef transforming_iterator<reverse_sub_iterator, selector>
00140                 const_reverse_iterator;
00141         typedef const_iterator iterator;
00142         typedef const_reverse_iterator reverse_iterator;
00143         typedef value_type& reference;
00144         typedef const value_type& const_reference;
00145         typedef value_type* pointer;
00146         typedef typename container::difference_type difference_type;
00147         typedef typename container::size_type size_type;
00148 
00149         degenerate_set() {}
00150         degenerate_set(degenerate_set const& x)
00151             : S(x.S) {}
00152         degenerate_set(key_compare const& kc)
00153             : S(sub_key_compare(kc)) {}
00154         degenerate_set& operator=(degenerate_set const& rhs) {
00155             S = rhs.S;
00156             return *this;
00157         }
00158 
00159 //      template<typename InputIterator>
00160 //        degenerate_set(InputIterator it, InputIterator it_end) {
00161 //            insert(it, it_end);
00162 //        }
00163 
00164 //      template<typename InputIterator>
00165 //        degenerate_set(InputIterator it, InputIterator it_end,
00166 //                       key_compare const& kc)
00167 //            : S(sub_key_compare(kc)) {
00168 //            insert(it, it_end);
00169 //        }
00170 
00171         bool operator==(degenerate_set const& rhs) const { return S == rhs.S; }
00172         bool operator!=(degenerate_set const& rhs) const { return S != rhs.S; }
00173         bool operator<(degenerate_set const& rhs) const { return S < rhs.S; }
00174         bool operator<=(degenerate_set const& rhs) const { return S <= rhs.S; }
00175         bool operator>(degenerate_set const& rhs) const { return S > rhs.S; }
00176         bool operator>=(degenerate_set const& rhs) const { return S >= rhs.S; }
00177 
00178         iterator begin() const { return iterator(S.begin()); }
00179         iterator end() const { return iterator(S.end()); }
00180         reverse_iterator rbegin() const
00181             { return reverse_iterator(S.rbegin()); }
00182         reverse_iterator rend() const
00183             { return reverse_iterator(S.rend()); }
00184 
00185         size_type size() const { return S.size(); }
00186         size_type max_size() const { return S.max_size(); }
00187         size_type empty() const { return S.empty(); }
00188         key_compare key_comp() const { return S.key_comp().subcomp; }
00189         value_compare value_comp() const { return S.key_comp().subcomp; }
00190         void swap(degenerate_set& x) { S.swap(x.S); }
00191 
00192         /** Insert \c x into the set. \return A pair of the iterator
00193          ** to the value, and the degeneracy of the value before the
00194          ** insertion. */
00195         std::pair<iterator, size_type>
00196         insert(const value_type& x)
00197         {
00198             sub_iterator it = S.find(sub_value_type(x));
00199             if (it == S.end()) {
00200                 std::pair<sub_iterator, bool> p
00201                     = S.insert(sub_value_type(x, 1));
00202                 return std::make_pair(iterator(p.first), 0);
00203             } else
00204                 return std::make_pair(iterator(it), it->degeneracy++);
00205         }
00206 
00207         /** Insert with hint. */
00208         std::pair<iterator, size_type>
00209         insert(iterator hint, const value_type& x)
00210         {
00211             return insert(x);
00212         }
00213 
00214         /** Increase the degneracy of \c it. \pre \c it must be a
00215          ** valid iterator pointing into this container. */
00216         std::pair<iterator, size_type>
00217         insert(iterator it)
00218         {
00219             return std::make_pair(it, it.sub_iterator()->degeneracy++);
00220         }
00221 
00222 //      template<typename InputIterator>
00223 //        void insert(InputIterator it, InputIterator it_end) {
00224 //            while (it != it_end) { insert(*it); ++it; }
00225 //        }
00226 
00227         /** Decrease the degeneracy of \c it, and remove if zero. \pre
00228          ** it must be a valid iterator in this container. */
00229         void erase(iterator it)
00230         {
00231             sub_iterator it0 = it.sub_iterator();
00232             if (--(*it0).degeneracy <= 0) S.erase(it0);
00233         }
00234 
00235         /** Erase a range of iterators. */
00236         void erase(iterator it, iterator it_end)
00237         {
00238             while (it != it_end) {
00239                 erase(it);
00240                 ++it;
00241             }
00242         }
00243         /** Sink the degeneracy of \c k, and remove if zero. */
00244         size_type erase(key_type const& k)
00245         {
00246             iterator it = find(k);
00247             if (it == end())
00248                 return 0;
00249             else {
00250                 erase(it);
00251                 return 1;
00252             }
00253         }
00254 
00255         iterator find(key_type const& k) const
00256         {
00257             sub_iterator it = S.find(sub_value_type(k));
00258             return iterator(it);
00259         }
00260 
00261         size_type count(key_type const& k) const { return S.count(k); }
00262 
00263         size_type degeneracy(iterator it) const
00264         {
00265             return (*it.sub_iterator()).degeneracy;
00266         }
00267 
00268         size_type degeneracy(key_type const& k) const
00269         {
00270             sub_iterator it = S.find(sub_value_type(k));
00271             if (it == S.end())
00272                 return 0;
00273             else
00274                 return (*it).degeneracy;
00275         }
00276 
00277         iterator lower_bound(const key_type& k) const
00278         {
00279             return iterator(S.lower_bound(k));
00280         }
00281 
00282         iterator upper_bound(const key_type& k) const
00283         {
00284             return iterator(S.upper_bound(k));
00285         }
00286 
00287         std::pair<iterator, iterator>
00288         equal_range(key_type const& k) const
00289         {
00290             std::pair<sub_iterator, sub_iterator> p = S.equal_range(k);
00291             return std::make_pair(iterator(p.first), iterator(p.second));
00292         }
00293 
00294       private:
00295         mutable container S;
00296     };
00297 }} // more::gen
00298 
00299 #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.