compare.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * Copyright 2001 Adrian Thurston <thurston@cs.queensu.ca>
  3. */
  4. /* This file is part of Aapl.
  5. *
  6. * Aapl is free software; you can redistribute it and/or modify it under the
  7. * terms of the GNU Lesser General Public License as published by the Free
  8. * Software Foundation; either version 2.1 of the License, or (at your option)
  9. * any later version.
  10. *
  11. * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY
  12. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Aapl; if not, write to the Free Software Foundation, Inc., 59
  18. * Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #ifndef _AAPL_COMPARE_H
  21. #define _AAPL_COMPARE_H
  22. #include <string.h>
  23. #include "table.h"
  24. #ifdef AAPL_NAMESPACE
  25. namespace Aapl {
  26. #endif
  27. /**
  28. * \defgroup compare Compare
  29. * \brief Basic compare clases.
  30. *
  31. * Compare classes are used by data structures that need to know the relative
  32. * ordering of elemets. To become a compare class, a class must imlement a
  33. * routine long compare(const T &key1, const T &key2) that behaves just like
  34. * strcmp.
  35. *
  36. * Compare classes are passed to the template data structure as a template
  37. * parameter and are inherited. In most cases the compare routine will base
  38. * the key comparision only on the two keys and the compare routine can
  39. * therefore be static. Though sometimes it is useful to include data in the
  40. * compare class and use this data in the comparison. For example the compare
  41. * class may contain a pointer to some other data structure to which the
  42. * comparison is delegated.
  43. *
  44. * @{
  45. */
  46. /**
  47. * \brief Compare two null terminated character sequences.
  48. *
  49. * This comparision class is a wrapper for strcmp.
  50. */
  51. struct CmpStr
  52. {
  53. /**
  54. * \brief Compare two null terminated string types.
  55. */
  56. static inline long compare(const char *k1, const char *k2)
  57. { return strcmp(k1, k2); }
  58. };
  59. /**
  60. * \brief Compare a type for which < and > are implemented.
  61. *
  62. * CmpOrd is suitable for simple types such as integers and pointers that by
  63. * default have the less-than and greater-than operators defined.
  64. */
  65. template <class T> struct CmpOrd
  66. {
  67. /**
  68. * \brief Compare two ordinal types.
  69. *
  70. * This compare routine copies its arguements in by value.
  71. */
  72. static inline long compare(const T k1, const T k2)
  73. {
  74. if (k1 < k2)
  75. return -1;
  76. else if (k1 > k2)
  77. return 1;
  78. else
  79. return 0;
  80. }
  81. };
  82. /**
  83. * \brief Compare two tables of type T
  84. *
  85. * Table comparison is useful for keying a data structure on a vector or
  86. * binary search table. T is the element type stored in the table.
  87. * CompareT is the comparison structure used to compare the individual values
  88. * in the table.
  89. */
  90. template < class T, class CompareT = CmpOrd<T> > struct CmpTable
  91. : public CompareT
  92. {
  93. /**
  94. * \brief Compare two tables storing type T.
  95. */
  96. static inline long compare(const Table<T> &t1, const Table<T> &t2)
  97. {
  98. if ( t1.tabLen < t2.tabLen )
  99. return -1;
  100. else if ( t1.tabLen > t2.tabLen )
  101. return 1;
  102. else
  103. {
  104. T *i1 = t1.data, *i2 = t2.data;
  105. long len = t1.tabLen, cmpResult;
  106. for ( long pos = 0; pos < len;
  107. pos += 1, i1 += 1, i2 += 1 )
  108. {
  109. cmpResult = CompareT::compare(*i1, *i2);
  110. if ( cmpResult != 0 )
  111. return cmpResult;
  112. }
  113. return 0;
  114. }
  115. }
  116. };
  117. /**
  118. * \brief Compare two tables of type T -- non-static version.
  119. *
  120. * CmpTableNs is identical to CmpTable, however the compare routine is
  121. * non-static. If the CompareT class contains a non-static compare, then this
  122. * version must be used because a static member cannot invoke a non-static
  123. * member.
  124. *
  125. * Table comparison is useful for keying a data structure on a vector or binary
  126. * search table. T is the element type stored in the table. CompareT
  127. * is the comparison structure used to compare the individual values in the
  128. * table.
  129. */
  130. template < class T, class CompareT = CmpOrd<T> > struct CmpTableNs
  131. : public CompareT
  132. {
  133. /**
  134. * \brief Compare two tables storing type T.
  135. */
  136. inline long compare(const Table<T> &t1, const Table<T> &t2)
  137. {
  138. if ( t1.tabLen < t2.tabLen )
  139. return -1;
  140. else if ( t1.tabLen > t2.tabLen )
  141. return 1;
  142. else
  143. {
  144. T *i1 = t1.data, *i2 = t2.data;
  145. long len = t1.tabLen, cmpResult;
  146. for ( long pos = 0; pos < len;
  147. pos += 1, i1 += 1, i2 += 1 )
  148. {
  149. cmpResult = CompareT::compare(*i1, *i2);
  150. if ( cmpResult != 0 )
  151. return cmpResult;
  152. }
  153. return 0;
  154. }
  155. }
  156. };
  157. /**
  158. * \brief Compare two implicitly shared tables of type T
  159. *
  160. * This table comparison is for data structures based on implicitly
  161. * shared tables.
  162. *
  163. * Table comparison is useful for keying a data structure on a vector or
  164. * binary search table. T is the element type stored in the table.
  165. * CompareT is the comparison structure used to compare the individual values
  166. * in the table.
  167. */
  168. template < class T, class CompareT = CmpOrd<T> > struct CmpSTable : public CompareT
  169. {
  170. /**
  171. * \brief Compare two tables storing type T.
  172. */
  173. static inline long compare(const STable<T> &t1, const STable<T> &t2)
  174. {
  175. long t1Length = t1.length();
  176. long t2Length = t2.length();
  177. /* Compare lengths. */
  178. if ( t1Length < t2Length )
  179. return -1;
  180. else if ( t1Length > t2Length )
  181. return 1;
  182. else {
  183. /* Compare the table data. */
  184. T *i1 = t1.data, *i2 = t2.data;
  185. for ( long pos = 0; pos < t1Length;
  186. pos += 1, i1 += 1, i2 += 1 )
  187. {
  188. long cmpResult = CompareT::compare(*i1, *i2);
  189. if ( cmpResult != 0 )
  190. return cmpResult;
  191. }
  192. return 0;
  193. }
  194. }
  195. };
  196. /**
  197. * \brief Compare two implicitly shared tables of type T -- non-static
  198. * version.
  199. *
  200. * This is a non-static table comparison for data structures based on
  201. * implicitly shared tables. If the CompareT class contains a non-static
  202. * compare, then this version must be used because a static member cannot
  203. * invoke a non-static member.
  204. *
  205. * Table comparison is useful for keying a data structure on a vector or
  206. * binary search table. T is the element type stored in the table.
  207. * CompareT is the comparison structure used to compare the individual values
  208. * in the table.
  209. */
  210. template < class T, class CompareT = CmpOrd<T> > struct CmpSTableNs
  211. : public CompareT
  212. {
  213. /**
  214. * \brief Compare two tables storing type T.
  215. */
  216. inline long compare(const STable<T> &t1, const STable<T> &t2)
  217. {
  218. long t1Length = t1.length();
  219. long t2Length = t2.length();
  220. /* Compare lengths. */
  221. if ( t1Length < t2Length )
  222. return -1;
  223. else if ( t1Length > t2Length )
  224. return 1;
  225. else {
  226. /* Compare the table data. */
  227. T *i1 = t1.data, *i2 = t2.data;
  228. for ( long pos = 0; pos < t1Length;
  229. pos += 1, i1 += 1, i2 += 1 )
  230. {
  231. long cmpResult = CompareT::compare(*i1, *i2);
  232. if ( cmpResult != 0 )
  233. return cmpResult;
  234. }
  235. return 0;
  236. }
  237. }
  238. };
  239. /*@}*/
  240. #ifdef AAPL_NAMESPACE
  241. }
  242. #endif
  243. #endif /* _AAPL_COMPARE_H */