ordered_vector.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // Filename: ordered_vector.h
  2. // Created by: drose (20Feb02)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #ifndef ORDERED_VECTOR_H
  19. #define ORDERED_VECTOR_H
  20. #ifdef CPPPARSER // hack around this for interigate...
  21. //****** HACK allert ***
  22. // this code is intended to tell interigate to not expand this class definition past basic names
  23. // It drops the interigate memory foot pront and user time by a bunch
  24. // on pc cygwin from 3 minutes to 17 seconds ?? really need to explore interigate to figure out what is
  25. // going on ..
  26. //
  27. template<class Key, class Compare = less<int> > class ov_multiset
  28. {
  29. };
  30. template<class Key, class Compare = less<int> > class ov_set
  31. {
  32. };
  33. template<class Key, class Compare = less<int> > class ordered_vector
  34. {
  35. };
  36. #else // cppparser
  37. #include "pandabase.h"
  38. #include "pvector.h"
  39. #include "pset.h"
  40. #include "pnotify.h"
  41. #include <algorithm>
  42. // There are some inheritance issues with template classes and typedef
  43. // names. Template classes that inherit typedef names from their base
  44. // class, which is also a template class, may confuse the typedef
  45. // names with globally scoped template names. In particular, the
  46. // local "iterator" type is easily confused with the std::iterator
  47. // template class.
  48. // To work around this problem, as well as a problem in gcc 2.95.3
  49. // with value_type etc. not inheriting properly (even though we
  50. // explicitly typedef them in the derived class), we rename the
  51. // questionable typedefs here so that they no longer conflict with the
  52. // global template classes.
  53. #define KEY_TYPE key_type_0
  54. #define VALUE_TYPE value_type_0
  55. #define REFERENCE reference_0
  56. #define CONST_REFERENCE const_reference_0
  57. #define KEY_COMPARE key_compare_0
  58. #define VALUE_COMPARE value_compare_0
  59. #define ITERATOR iterator_0
  60. #define CONST_ITERATOR const_iterator_0
  61. #define REVERSE_ITERATOR reverse_iterator_0
  62. #define CONST_REVERSE_ITERATOR const_reverse_iterator_0
  63. #define DIFFERENCE_TYPE difference_type_0
  64. #define SIZE_TYPE size_type_0
  65. ////////////////////////////////////////////////////////////////////
  66. // Class : ordered_vector
  67. // Description : This template class presents an interface similar to
  68. // the STL set or multiset (and ov_set and ov_multiset
  69. // are implemented specifically, below), but it is
  70. // implemented using a vector that is kept always in
  71. // sorted order.
  72. //
  73. // In most cases, an ov_set or ov_multiset may be
  74. // dropped in transparently in place of a set or
  75. // multiset, but the implementation difference has a few
  76. // implications:
  77. //
  78. // (1) The ov_multiset will maintain stability of order
  79. // between elements that sort equally: they are stored
  80. // in the order in which they were added, from back to
  81. // front.
  82. //
  83. // (2) Insert and erase operations into the middle of
  84. // the set can be slow, just as inserting into the
  85. // middle of a vector can be slow. In fact, building up
  86. // an ov_set by inserting elements one at a time is an
  87. // n^2 operation. On the other hand, building up an
  88. // ov_set by adding elements to the end, one at time, is
  89. // somewhat faster than building up a traditional set;
  90. // and you can even add unsorted elements with
  91. // push_back() and then call sort() when you're done,
  92. // for a log(n) operation.
  93. //
  94. // (3) Iterators may not be valid for the life of the
  95. // ordered_vector. If the vector reallocates itself,
  96. // all iterators are invalidated.
  97. //
  98. // (4) Random access into the set is easy with the []
  99. // operator.
  100. ////////////////////////////////////////////////////////////////////
  101. template<class Key, class Compare = less<Key> >
  102. class ordered_vector {
  103. private:
  104. typedef pvector<Key> Vector;
  105. public:
  106. // Typedefs
  107. typedef Key KEY_TYPE;
  108. typedef Key VALUE_TYPE;
  109. typedef Key &REFERENCE;
  110. typedef const Key &CONST_REFERENCE;
  111. typedef Compare KEY_COMPARE;
  112. typedef Compare VALUE_COMPARE;
  113. // Be careful when using the non-const iterators that you do not
  114. // disturb the sorted order of the vector, or that if you do, you
  115. // call sort() when you are done.
  116. typedef TYPENAME Vector::iterator ITERATOR;
  117. typedef TYPENAME Vector::const_iterator CONST_ITERATOR;
  118. typedef TYPENAME Vector::reverse_iterator REVERSE_ITERATOR;
  119. typedef TYPENAME Vector::const_reverse_iterator CONST_REVERSE_ITERATOR;
  120. typedef TYPENAME Vector::difference_type DIFFERENCE_TYPE;
  121. typedef TYPENAME Vector::size_type SIZE_TYPE;
  122. // Since the #define symbols do not actually expand to the correct
  123. // names, we have to re-typedef them so callers can reference them
  124. // by their correct, lowercase names.
  125. typedef KEY_TYPE key_type;
  126. typedef VALUE_TYPE value_type;
  127. typedef REFERENCE reference;
  128. typedef CONST_REFERENCE const_reference;
  129. typedef KEY_COMPARE key_compare;
  130. typedef VALUE_COMPARE value_compare;
  131. typedef ITERATOR iterator;
  132. typedef CONST_ITERATOR const_iterator;
  133. typedef REVERSE_ITERATOR reverse_iterator;
  134. typedef CONST_REVERSE_ITERATOR const_reverse_iterator;
  135. typedef DIFFERENCE_TYPE difference_type;
  136. typedef SIZE_TYPE size_type;
  137. public:
  138. // Constructors. We don't implement the whole slew of STL
  139. // constructors here yet.
  140. INLINE ordered_vector(const Compare &compare = Compare());
  141. INLINE ordered_vector(const ordered_vector<Key, Compare> &copy);
  142. INLINE ordered_vector<Key, Compare> &operator = (const ordered_vector<Key, Compare> &copy);
  143. INLINE ~ordered_vector();
  144. // Iterator access.
  145. INLINE ITERATOR begin();
  146. INLINE ITERATOR end();
  147. INLINE REVERSE_ITERATOR rbegin();
  148. INLINE REVERSE_ITERATOR rend();
  149. INLINE CONST_ITERATOR begin() const;
  150. INLINE CONST_ITERATOR end() const;
  151. INLINE CONST_REVERSE_ITERATOR rbegin() const;
  152. INLINE CONST_REVERSE_ITERATOR rend() const;
  153. // Random access.
  154. INLINE reference operator [] (SIZE_TYPE n);
  155. INLINE const_reference operator [] (SIZE_TYPE n) const;
  156. // Size information.
  157. INLINE SIZE_TYPE size() const;
  158. INLINE SIZE_TYPE max_size() const;
  159. INLINE bool empty() const;
  160. // Equivalence and lexicographical comparisons.
  161. INLINE bool operator == (const ordered_vector<Key, Compare> &other) const;
  162. INLINE bool operator != (const ordered_vector<Key, Compare> &other) const;
  163. INLINE bool operator < (const ordered_vector<Key, Compare> &other) const;
  164. INLINE bool operator > (const ordered_vector<Key, Compare> &other) const;
  165. INLINE bool operator <= (const ordered_vector<Key, Compare> &other) const;
  166. INLINE bool operator >= (const ordered_vector<Key, Compare> &other) const;
  167. // Insert operations.
  168. ITERATOR insert_unique(ITERATOR position, const VALUE_TYPE &key);
  169. ITERATOR insert_nonunique(ITERATOR position, const VALUE_TYPE &key);
  170. INLINE pair<ITERATOR, bool> insert_unique(const VALUE_TYPE &key);
  171. INLINE ITERATOR insert_nonunique(const VALUE_TYPE &key);
  172. // Erase operations.
  173. INLINE ITERATOR erase(ITERATOR position);
  174. INLINE SIZE_TYPE erase(const KEY_TYPE &key);
  175. INLINE void erase(ITERATOR first, ITERATOR last);
  176. INLINE void clear();
  177. // Find operations.
  178. INLINE ITERATOR find(const KEY_TYPE &key);
  179. INLINE CONST_ITERATOR find(const KEY_TYPE &key) const;
  180. INLINE ITERATOR find_particular(const KEY_TYPE &key);
  181. INLINE CONST_ITERATOR find_particular(const KEY_TYPE &key) const;
  182. INLINE SIZE_TYPE count(const KEY_TYPE &key) const;
  183. INLINE ITERATOR lower_bound(const KEY_TYPE &key);
  184. INLINE CONST_ITERATOR lower_bound(const KEY_TYPE &key) const;
  185. INLINE ITERATOR upper_bound(const KEY_TYPE &key);
  186. INLINE CONST_ITERATOR upper_bound(const KEY_TYPE &key) const;
  187. INLINE pair<ITERATOR, ITERATOR> equal_range(const KEY_TYPE &key);
  188. INLINE pair<CONST_ITERATOR, CONST_ITERATOR> equal_range(const KEY_TYPE &key) const;
  189. // Special operations.
  190. INLINE void swap(ordered_vector<Key, Compare> &other);
  191. INLINE void reserve(SIZE_TYPE n);
  192. INLINE void sort_unique();
  193. INLINE void sort_nonunique();
  194. bool verify_list_unique() const;
  195. bool verify_list_nonunique() const;
  196. INLINE void push_back(const VALUE_TYPE &key);
  197. INLINE void pop_back();
  198. private:
  199. INLINE ITERATOR nci(CONST_ITERATOR i);
  200. INLINE ITERATOR find_insert_position(ITERATOR first, ITERATOR last,
  201. const KEY_TYPE &key);
  202. ITERATOR r_find_insert_position(ITERATOR first, ITERATOR last,
  203. const KEY_TYPE &key);
  204. CONST_ITERATOR r_find(CONST_ITERATOR first, CONST_ITERATOR last,
  205. CONST_ITERATOR not_found,
  206. const KEY_TYPE &key) const;
  207. CONST_ITERATOR r_find_particular(CONST_ITERATOR first, CONST_ITERATOR last,
  208. CONST_ITERATOR not_found,
  209. const KEY_TYPE &key) const;
  210. SIZE_TYPE r_count(CONST_ITERATOR first, CONST_ITERATOR last,
  211. const KEY_TYPE &key) const;
  212. CONST_ITERATOR r_lower_bound(CONST_ITERATOR first, CONST_ITERATOR last,
  213. const KEY_TYPE &key) const;
  214. CONST_ITERATOR r_upper_bound(CONST_ITERATOR first, CONST_ITERATOR last,
  215. const KEY_TYPE &key) const;
  216. pair<CONST_ITERATOR, CONST_ITERATOR>
  217. r_equal_range(CONST_ITERATOR first, CONST_ITERATOR last,
  218. const KEY_TYPE &key) const;
  219. // This function object is used in sort_unique(). It returns true
  220. // if two consecutive sorted elements are equivalent.
  221. class EquivalentTest {
  222. public:
  223. // For some reason, VC++ won't allow us to define these bodies
  224. // outside the class; they must be defined here. The error
  225. // message is C3206: "member functions of nested classes of a
  226. // template class cannot be defined outside the class".
  227. INLINE EquivalentTest(const Compare &compare) :
  228. _compare(compare) { }
  229. INLINE bool operator () (const KEY_TYPE &a, const KEY_TYPE &b) {
  230. nassertr(!_compare(b, a), false);
  231. return !_compare(a, b);
  232. }
  233. Compare _compare;
  234. };
  235. Compare _compare;
  236. Vector _vector;
  237. };
  238. ////////////////////////////////////////////////////////////////////
  239. // Class : ov_set
  240. // Description : A specialization of ordered_vector that emulates a
  241. // standard STL set: one copy of each element is
  242. // allowed.
  243. ////////////////////////////////////////////////////////////////////
  244. template<class Key, class Compare = less<Key> >
  245. class ov_set : public ordered_vector<Key, Compare> {
  246. public:
  247. typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
  248. typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
  249. INLINE ov_set(const Compare &compare = Compare());
  250. INLINE ov_set(const ov_set<Key, Compare> &copy);
  251. INLINE ov_set<Key, Compare> &operator = (const ov_set<Key, Compare> &copy);
  252. INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key0);
  253. INLINE pair<ITERATOR, bool> insert(const VALUE_TYPE &key0);
  254. INLINE void sort();
  255. INLINE bool verify_list() const;
  256. };
  257. ////////////////////////////////////////////////////////////////////
  258. // Class : ov_multiset
  259. // Description : A specialization of ordered_vector that emulates a
  260. // standard STL set: many copies of each element are
  261. // allowed.
  262. ////////////////////////////////////////////////////////////////////
  263. template<class Key, class Compare = less<Key> >
  264. class ov_multiset : public ordered_vector<Key, Compare> {
  265. public:
  266. typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
  267. typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
  268. INLINE ov_multiset(const Compare &compare = Compare());
  269. INLINE ov_multiset(const ov_multiset<Key, Compare> &copy);
  270. INLINE ov_multiset<Key, Compare> &operator = (const ov_multiset<Key, Compare> &copy);
  271. INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key);
  272. INLINE ITERATOR insert(const VALUE_TYPE &key);
  273. INLINE void sort();
  274. INLINE bool verify_list() const;
  275. };
  276. #include "ordered_vector.I"
  277. #include "ordered_vector.T"
  278. #endif // cppparser ..
  279. #endif