Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/express/ordered_vector.h

Go to the documentation of this file.
00001 // Filename: ordered_vector.h
00002 // Created by:  drose (20Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef ORDERED_VECTOR_H
00020 #define ORDERED_VECTOR_H
00021 
00022 #include "pandabase.h"
00023 
00024 #include "pvector.h"
00025 #include "pset.h"
00026 #include "notify.h"
00027 #include <algorithm>
00028 
00029 // There are some inheritance issues with template classes and typedef
00030 // names.  Template classes that inherit typedef names from their base
00031 // class, which is also a template class, may confuse the typedef
00032 // names with globally scoped template names.  In particular, the
00033 // local "iterator" type is easily confused with the std::iterator
00034 // template class.
00035 
00036 // To work around this problem, as well as a problem in gcc 2.95.3
00037 // with value_type etc. not inheriting properly (even though we
00038 // explicitly typedef them in the derived class), we rename the
00039 // questionable typedefs here so that they no longer conflict with the
00040 // global template classes.
00041 
00042 #define KEY_TYPE key_type_0
00043 #define VALUE_TYPE value_type_0
00044 #define REFERENCE reference_0
00045 #define CONST_REFERENCE const_reference_0
00046 #define KEY_COMPARE key_compare_0
00047 #define VALUE_COMPARE value_compare_0
00048 #define ITERATOR iterator_0
00049 #define CONST_ITERATOR const_iterator_0
00050 #define REVERSE_ITERATOR reverse_iterator_0
00051 #define CONST_REVERSE_ITERATOR const_reverse_iterator_0
00052 #define DIFFERENCE_TYPE difference_type_0
00053 #define SIZE_TYPE size_type_0
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //       Class : ordered_vector
00057 // Description : This template class presents an interface similar to
00058 //               the STL set or multiset (and ov_set and ov_multiset
00059 //               are implemented specifically, below), but it is
00060 //               implemented using a vector that is kept always in
00061 //               sorted order.
00062 //
00063 //               In most cases, an ov_set or ov_multiset may be
00064 //               dropped in transparently in place of a set or
00065 //               multiset, but the implementation difference has a few
00066 //               implications:
00067 //
00068 //               (1) The ov_multiset will maintain stability of order
00069 //               between elements that sort equally: they are stored
00070 //               in the order in which they were added, from back to
00071 //               front.
00072 //
00073 //               (2) Insert and erase operations into the middle of
00074 //               the set can be slow, just as inserting into the
00075 //               middle of a vector can be slow.  In fact, building up
00076 //               an ov_set by inserting elements one at a time is an
00077 //               n^2 operation.  On the other hand, building up an
00078 //               ov_set by adding elements to the end, one at time, is
00079 //               somewhat faster than building up a traditional set;
00080 //               and you can even add unsorted elements with
00081 //               push_back() and then call sort() when you're done,
00082 //               for a log(n) operation.
00083 //
00084 //               (3) Iterators may not be valid for the life of the
00085 //               ordered_vector.  If the vector reallocates itself,
00086 //               all iterators are invalidated.
00087 //
00088 //               (4) Random access into the set is easy with the []
00089 //               operator.
00090 ////////////////////////////////////////////////////////////////////
00091 template<class Key, class Compare = less<Key> >
00092 class ordered_vector {
00093 private:
00094   typedef pvector<Key> Vector;
00095   
00096 public:
00097   // Typedefs
00098   typedef Key KEY_TYPE;
00099   typedef Key VALUE_TYPE;
00100   typedef Key &REFERENCE;
00101   typedef const Key &CONST_REFERENCE;
00102   typedef Compare KEY_COMPARE;
00103   typedef Compare VALUE_COMPARE;
00104 
00105   // Be careful when using the non-const iterators that you do not
00106   // disturb the sorted order of the vector, or that if you do, you
00107   // call sort() when you are done.
00108   typedef TYPENAME Vector::iterator ITERATOR;
00109   typedef TYPENAME Vector::const_iterator CONST_ITERATOR;
00110   typedef TYPENAME Vector::reverse_iterator REVERSE_ITERATOR;
00111   typedef TYPENAME Vector::const_reverse_iterator CONST_REVERSE_ITERATOR;
00112 
00113   typedef TYPENAME Vector::difference_type DIFFERENCE_TYPE;
00114   typedef TYPENAME Vector::size_type SIZE_TYPE;
00115 
00116   // Since the #define symbols do not actually expand to the correct
00117   // names, we have to re-typedef them so callers can reference them
00118   // by their correct, lowercase names.
00119   typedef KEY_TYPE key_type;
00120   typedef VALUE_TYPE value_type;
00121   typedef REFERENCE reference;
00122   typedef CONST_REFERENCE const_reference;
00123   typedef KEY_COMPARE key_compare;
00124   typedef VALUE_COMPARE value_compare;
00125   typedef ITERATOR iterator;
00126   typedef CONST_ITERATOR const_iterator;
00127   typedef REVERSE_ITERATOR reverse_iterator;
00128   typedef CONST_REVERSE_ITERATOR const_reverse_iterator;
00129   typedef DIFFERENCE_TYPE difference_type;
00130   typedef SIZE_TYPE size_type;
00131 
00132 public:
00133   // Constructors.  We don't implement the whole slew of STL
00134   // constructors here yet.
00135   INLINE ordered_vector(const Compare &compare = Compare());
00136   INLINE ordered_vector(const ordered_vector<Key, Compare> &copy);
00137   INLINE ordered_vector<Key, Compare> &operator = (const ordered_vector<Key, Compare> &copy);
00138   INLINE ~ordered_vector();
00139 
00140   // Iterator access.
00141   INLINE ITERATOR begin();
00142   INLINE ITERATOR end();
00143   INLINE REVERSE_ITERATOR rbegin();
00144   INLINE REVERSE_ITERATOR rend();
00145 
00146   INLINE CONST_ITERATOR begin() const;
00147   INLINE CONST_ITERATOR end() const;
00148   INLINE CONST_REVERSE_ITERATOR rbegin() const;
00149   INLINE CONST_REVERSE_ITERATOR rend() const;
00150 
00151   // Random access.
00152   INLINE reference operator [] (SIZE_TYPE n);
00153   INLINE const_reference operator [] (SIZE_TYPE n) const;
00154 
00155   // Size information.
00156   INLINE SIZE_TYPE size() const;
00157   INLINE SIZE_TYPE max_size() const;
00158   INLINE bool empty() const;
00159 
00160   // Equivalence and lexicographical comparisons.
00161   INLINE bool operator == (const ordered_vector<Key, Compare> &other) const;
00162   INLINE bool operator != (const ordered_vector<Key, Compare> &other) const;
00163 
00164   INLINE bool operator < (const ordered_vector<Key, Compare> &other) const;
00165   INLINE bool operator > (const ordered_vector<Key, Compare> &other) const;
00166   INLINE bool operator <= (const ordered_vector<Key, Compare> &other) const;
00167   INLINE bool operator >= (const ordered_vector<Key, Compare> &other) const;
00168 
00169   // Insert operations.
00170   ITERATOR insert_unique(ITERATOR position, const VALUE_TYPE &key);
00171   ITERATOR insert_nonunique(ITERATOR position, const VALUE_TYPE &key);
00172   INLINE pair<ITERATOR, bool> insert_unique(const VALUE_TYPE &key);
00173   INLINE ITERATOR insert_nonunique(const VALUE_TYPE &key);
00174 
00175   // Erase operations.
00176   INLINE ITERATOR erase(ITERATOR position);
00177   INLINE SIZE_TYPE erase(const KEY_TYPE &key);
00178   INLINE void erase(ITERATOR first, ITERATOR last);
00179   INLINE void clear();
00180 
00181   // Find operations.
00182   INLINE ITERATOR find(const KEY_TYPE &key);
00183   INLINE CONST_ITERATOR find(const KEY_TYPE &key) const;
00184   INLINE ITERATOR find_particular(const KEY_TYPE &key);
00185   INLINE CONST_ITERATOR find_particular(const KEY_TYPE &key) const;
00186   INLINE SIZE_TYPE count(const KEY_TYPE &key) const;
00187 
00188   INLINE ITERATOR lower_bound(const KEY_TYPE &key);
00189   INLINE CONST_ITERATOR lower_bound(const KEY_TYPE &key) const;
00190   INLINE ITERATOR upper_bound(const KEY_TYPE &key);
00191   INLINE CONST_ITERATOR upper_bound(const KEY_TYPE &key) const;
00192   INLINE pair<ITERATOR, ITERATOR> equal_range(const KEY_TYPE &key);
00193   INLINE pair<CONST_ITERATOR, CONST_ITERATOR> equal_range(const KEY_TYPE &key) const;
00194 
00195   // Special operations.
00196   INLINE void swap(ordered_vector<Key, Compare> &other);
00197   INLINE void reserve(SIZE_TYPE n);
00198   INLINE void sort_unique();
00199   INLINE void sort_nonunique();
00200   bool verify_list_unique() const;
00201   bool verify_list_nonunique() const;
00202 
00203   INLINE void push_back(const VALUE_TYPE &key);
00204 
00205 private:
00206   INLINE ITERATOR nci(CONST_ITERATOR i);
00207   INLINE ITERATOR find_insert_position(ITERATOR first, ITERATOR last, 
00208                                        const KEY_TYPE &key);
00209   ITERATOR r_find_insert_position(ITERATOR first, ITERATOR last, 
00210                                   const KEY_TYPE &key);
00211   CONST_ITERATOR r_find(CONST_ITERATOR first, CONST_ITERATOR last,
00212                         CONST_ITERATOR not_found,
00213                         const KEY_TYPE &key) const;
00214   CONST_ITERATOR r_find_particular(CONST_ITERATOR first, CONST_ITERATOR last,
00215                                    CONST_ITERATOR not_found,
00216                                    const KEY_TYPE &key) const;
00217   SIZE_TYPE r_count(CONST_ITERATOR first, CONST_ITERATOR last,
00218                     const KEY_TYPE &key) const;
00219   CONST_ITERATOR r_lower_bound(CONST_ITERATOR first, CONST_ITERATOR last,
00220                                const KEY_TYPE &key) const;
00221   CONST_ITERATOR r_upper_bound(CONST_ITERATOR first, CONST_ITERATOR last,
00222                                const KEY_TYPE &key) const;
00223   pair<CONST_ITERATOR, CONST_ITERATOR>
00224   r_equal_range(CONST_ITERATOR first, CONST_ITERATOR last,
00225                 const KEY_TYPE &key) const;
00226 
00227   // This function object is used in sort_unique().  It returns true
00228   // if two consecutive sorted elements are equivalent.
00229   class EquivalentTest {
00230   public:
00231     // For some reason, VC++ won't allow us to define these bodies
00232     // outside the class; they must be defined here.  The error
00233     // message is C3206: "member functions of nested classes of a
00234     // template class cannot be defined outside the class".
00235     INLINE EquivalentTest(const Compare &compare) :
00236       _compare(compare) { }
00237     INLINE bool operator () (const KEY_TYPE &a, const KEY_TYPE &b) {
00238       nassertr(!_compare(b, a), false);
00239       return !_compare(a, b);
00240     }
00241 
00242     Compare _compare;
00243   };
00244 
00245   Compare _compare;
00246   Vector _vector;
00247 };
00248 
00249 ////////////////////////////////////////////////////////////////////
00250 //       Class : ov_set
00251 // Description : A specialization of ordered_vector that emulates a
00252 //               standard STL set: one copy of each element is
00253 //               allowed.
00254 ////////////////////////////////////////////////////////////////////
00255 template<class Key, class Compare = less<Key> >
00256 class ov_set : public ordered_vector<Key, Compare> {
00257 public:
00258   typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
00259   typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
00260 
00261   INLINE ov_set(const Compare &compare = Compare());
00262   INLINE ov_set(const ov_set<Key, Compare> &copy);
00263   INLINE ov_set<Key, Compare> &operator = (const ov_set<Key, Compare> &copy);
00264 
00265   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key0);
00266   INLINE pair<ITERATOR, bool> insert(const VALUE_TYPE &key0);
00267 
00268   INLINE void sort();
00269   INLINE bool verify_list() const;
00270 };
00271 
00272 ////////////////////////////////////////////////////////////////////
00273 //       Class : ov_multiset
00274 // Description : A specialization of ordered_vector that emulates a
00275 //               standard STL set: many copies of each element are
00276 //               allowed.
00277 ////////////////////////////////////////////////////////////////////
00278 template<class Key, class Compare = less<Key> >
00279 class ov_multiset : public ordered_vector<Key, Compare> {
00280 public:
00281   typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
00282   typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
00283 
00284   INLINE ov_multiset(const Compare &compare = Compare());
00285   INLINE ov_multiset(const ov_multiset<Key, Compare> &copy);
00286   INLINE ov_multiset<Key, Compare> &operator = (const ov_multiset<Key, Compare> &copy);
00287 
00288   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key);
00289   INLINE ITERATOR insert(const VALUE_TYPE &key);
00290 
00291   INLINE void sort();
00292   INLINE bool verify_list() const;
00293 };
00294 
00295 #include "ordered_vector.I"
00296 #include "ordered_vector.T"
00297 
00298 #endif

Generated on Fri May 2 00:38:28 2003 for Panda by doxygen1.3