Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

463 lines
11 KiB

  1. /**************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * Iterator definitions.
  8. *
  9. * Abstract:
  10. *
  11. * Describes a general iterator interface.
  12. *
  13. * Created:
  14. *
  15. * 09/01/2000 asecchia
  16. * Created it.
  17. *
  18. **************************************************************************/
  19. #ifndef _ITERATOR_HPP
  20. #define _ITERATOR_HPP
  21. /**************************************************************************\
  22. *
  23. * Class Description:
  24. *
  25. * This is an interface for a general list iterator.
  26. * See Design Patterns (Erich Gamma, et al) pp 257 ITERATOR pattern.
  27. *
  28. * Interface:
  29. * SeekFirst() - set the current pointer (CP) to the beginning of the list
  30. * SeekLast() - set CP to the end of the list.
  31. * CurrentItem() - return a pointer to the current item.
  32. * CurrentIndex() - return the value of CP (index into the array)
  33. * Next() - advance CP by one element
  34. * Prev() - rewind CP by one element
  35. * IsDone() - are we beyond either end of the list.
  36. *
  37. * History:
  38. *
  39. * 09/01/2000 asecchia created it
  40. *
  41. \**************************************************************************/
  42. template<class T>
  43. class GpIterator
  44. {
  45. public:
  46. virtual void SeekFirst() = 0;
  47. virtual void SeekLast() = 0;
  48. virtual T *CurrentItem() const = 0;
  49. virtual INT CurrentIndex() const = 0;
  50. virtual void Next() = 0;
  51. virtual void Prev() = 0;
  52. virtual BOOL IsDone() = 0;
  53. // Used for our debug tracking. Make all GpIterator objects allocated using
  54. // the default new operator have an appropriate tag.
  55. // Most often, however, iterators will be stack allocations.
  56. void *(operator new)(size_t in_size)
  57. {
  58. return ::operator new (in_size, GpIteratorTag, FALSE);
  59. }
  60. void *(operator new[])(size_t in_size)
  61. {
  62. return ::operator new[] (in_size, GpIteratorTag, FALSE);
  63. }
  64. };
  65. /**************************************************************************\
  66. *
  67. * Class Description:
  68. *
  69. * This is a PROXY iterator that adds the behaviour of
  70. * wrapping the list when the end is encountered.
  71. *
  72. * See Design Patterns (Erich Gamma, et al) pp 207 for the
  73. * definition of a PROXY
  74. *
  75. * Interface:
  76. * ... see GpIterator ...
  77. * IsDone() - private - unimplemented. Not meaningful for
  78. * circular lists
  79. *
  80. * History:
  81. *
  82. * 09/01/2000 asecchia created it
  83. *
  84. \**************************************************************************/
  85. template<class T>
  86. class GpCircularIterator : public GpIterator<T>
  87. {
  88. GpIterator<T> *iterator;
  89. public:
  90. GpCircularIterator(GpIterator<T> *_iterator)
  91. {
  92. iterator = _iterator;
  93. }
  94. virtual void SeekFirst()
  95. {
  96. iterator->SeekFirst();
  97. }
  98. virtual void SeekLast()
  99. {
  100. iterator->SeekLast();
  101. }
  102. virtual void Next()
  103. {
  104. ASSERT(!iterator->IsDone());
  105. iterator->Next();
  106. if(iterator->IsDone())
  107. {
  108. iterator->SeekFirst();
  109. }
  110. }
  111. virtual void Prev()
  112. {
  113. ASSERT(!iterator->IsDone());
  114. iterator->Prev();
  115. if(iterator->IsDone())
  116. {
  117. iterator->SeekLast();
  118. }
  119. }
  120. virtual T *CurrentItem() const
  121. {
  122. return iterator->CurrentItem();
  123. }
  124. virtual INT CurrentIndex() const
  125. {
  126. return iterator->CurrentIndex();
  127. }
  128. private:
  129. // It's not meaningful to call IsDone on a circular iterator.
  130. virtual BOOL IsDone() {
  131. ASSERT(FALSE);
  132. return FALSE;
  133. }
  134. };
  135. /**************************************************************************\
  136. *
  137. * Class Description:
  138. *
  139. * This is a PROXY iterator that modifies the behaviour of the
  140. * underlying iterator by making it traverse the list backwards.
  141. *
  142. * Interface:
  143. * ... see GpIterator ...
  144. *
  145. * Note the sense of the following interfaces is reversed.
  146. *
  147. * SeekFirst() - Call proxy SeekLast()
  148. * SeekLast() - Call proxy SeekFirst()
  149. * Next() - Call proxy Prev()
  150. * Prev() - Call proxy Next()
  151. *
  152. * History:
  153. *
  154. * 09/01/2000 asecchia created it
  155. *
  156. \**************************************************************************/
  157. template<class T>
  158. class GpReverseIterator : public GpIterator<T>
  159. {
  160. GpIterator<T> *iterator;
  161. public:
  162. GpReverseIterator(GpIterator<T> *_iterator)
  163. {
  164. iterator = _iterator;
  165. }
  166. virtual GpIterator<T> *GetIterator()
  167. {
  168. return iterator;
  169. }
  170. virtual void SeekFirst()
  171. {
  172. iterator->SeekLast();
  173. }
  174. virtual void SeekLast()
  175. {
  176. iterator->SeekFirst();
  177. }
  178. virtual void Next()
  179. {
  180. iterator->Prev();
  181. }
  182. virtual void Prev()
  183. {
  184. iterator->Next();
  185. }
  186. virtual T *CurrentItem() const
  187. {
  188. return iterator->CurrentItem();
  189. }
  190. virtual INT CurrentIndex() const
  191. {
  192. return iterator->CurrentIndex();
  193. }
  194. virtual BOOL IsDone()
  195. {
  196. return iterator->IsDone();
  197. }
  198. };
  199. /**************************************************************************\
  200. *
  201. * Class Description:
  202. *
  203. * This is a concrete iterator for an arbitrary C array of objects
  204. * The constructor takes the array pointer and the number of elements
  205. * and the iterator is constructed to traverse the elements in the
  206. * standard (forward) direction.
  207. *
  208. * Interface:
  209. * ... see GpIterator ...
  210. *
  211. * History:
  212. *
  213. * 09/01/2000 asecchia created it
  214. *
  215. \**************************************************************************/
  216. template<class T>
  217. class GpArrayIterator : public GpIterator<T>
  218. {
  219. public:
  220. GpArrayIterator(T *array, INT count)
  221. {
  222. Array = array;
  223. Count = count;
  224. SeekFirst();
  225. }
  226. virtual void SeekFirst()
  227. {
  228. CurrentItemPosition = 0;
  229. }
  230. virtual void SeekLast()
  231. {
  232. CurrentItemPosition = Count-1;
  233. }
  234. virtual T *CurrentItem() const
  235. {
  236. ASSERT(CurrentItemPosition >= 0);
  237. ASSERT(CurrentItemPosition < Count);
  238. return Array+CurrentItemPosition;
  239. }
  240. virtual INT CurrentIndex() const
  241. {
  242. return CurrentItemPosition;
  243. }
  244. virtual void Next()
  245. {
  246. CurrentItemPosition++;
  247. }
  248. virtual void Prev()
  249. {
  250. CurrentItemPosition--;
  251. }
  252. virtual BOOL IsDone()
  253. {
  254. return (CurrentItemPosition < 0 ||
  255. CurrentItemPosition >= Count);
  256. }
  257. private:
  258. T *Array;
  259. INT Count;
  260. // Internal State
  261. INT CurrentItemPosition;
  262. };
  263. /**************************************************************************\
  264. *
  265. * Class Description:
  266. *
  267. * This is a concrete iterator for a set of path points.
  268. * Path points are defined by an array of GpPointFs and an array
  269. * of BYTEs representing the point types. Both arrays are of size
  270. * count and have to be kept in step with each other.
  271. *
  272. * Interface:
  273. * ... see GpIterator ...
  274. *
  275. * We extend the interface with this class by defining the
  276. * point array to be the primary sub iterator and providing
  277. * a CurrentType() method to return the current item in the
  278. * type array.
  279. *
  280. * History:
  281. *
  282. * 09/03/2000 asecchia created it
  283. *
  284. \**************************************************************************/
  285. class GpPathPointIterator : public GpIterator<GpPointF>
  286. {
  287. public:
  288. GpPathPointIterator(GpPointF *points, BYTE *types, INT count) :
  289. _points(points, count),
  290. _types(types, count)
  291. {
  292. SeekFirst();
  293. }
  294. virtual void SeekFirst()
  295. {
  296. _points.SeekFirst();
  297. _types.SeekFirst();
  298. }
  299. virtual void SeekLast()
  300. {
  301. _points.SeekLast();
  302. _types.SeekLast();
  303. }
  304. virtual GpPointF *CurrentItem() const
  305. {
  306. return _points.CurrentItem();
  307. }
  308. virtual BYTE *CurrentType() const
  309. {
  310. return _types.CurrentItem();
  311. }
  312. virtual INT CurrentIndex() const
  313. {
  314. return _points.CurrentIndex();
  315. }
  316. virtual void Next()
  317. {
  318. _points.Next();
  319. _types.Next();
  320. }
  321. virtual void Prev()
  322. {
  323. _points.Prev();
  324. _types.Prev();
  325. }
  326. virtual BOOL IsDone()
  327. {
  328. return _points.IsDone();
  329. }
  330. private:
  331. GpArrayIterator<GpPointF> _points;
  332. GpArrayIterator<BYTE> _types;
  333. };
  334. /**************************************************************************\
  335. *
  336. * Class Description:
  337. *
  338. * This is a PROXY iterator for a GpPathPointIterator that advances
  339. * the base GpPathPointIterator to the next subpath defined by the
  340. * start marker in the types array.
  341. *
  342. * Interface:
  343. * ... see GpIterator ...
  344. *
  345. * History:
  346. *
  347. * 09/03/2000 asecchia created it
  348. *
  349. \**************************************************************************/
  350. class GpSubpathIterator : public GpIterator<GpPointF>
  351. {
  352. public:
  353. GpSubpathIterator(GpPathPointIterator *iterator)
  354. {
  355. _iterator = iterator;
  356. }
  357. virtual void SeekFirst()
  358. {
  359. _iterator->SeekFirst();
  360. }
  361. virtual void SeekLast()
  362. {
  363. _iterator->SeekLast();
  364. }
  365. virtual GpPointF *CurrentItem() const { return _iterator->CurrentItem(); }
  366. virtual BYTE *CurrentType() const { return _iterator->CurrentType(); }
  367. virtual INT CurrentIndex() const { return _iterator->CurrentIndex(); }
  368. virtual void Next()
  369. {
  370. // Call the base _iterator Next() method till either we run out of
  371. // path or we encounter another PathPointTypeStart marker.
  372. do {
  373. _iterator->Next();
  374. } while (
  375. !_iterator->IsDone() &&
  376. ((*_iterator->CurrentType() & PathPointTypePathTypeMask) !=
  377. PathPointTypeStart)
  378. );
  379. }
  380. virtual void Prev()
  381. {
  382. // Call the base _iterator Prev() method till either we run out of
  383. // path or we encounter another PathPointTypeStart marker.
  384. do {
  385. _iterator->Prev();
  386. } while (
  387. !_iterator->IsDone() &&
  388. ((*_iterator->CurrentType() & PathPointTypePathTypeMask) !=
  389. PathPointTypeStart)
  390. );
  391. }
  392. virtual BOOL IsDone() { return _iterator->IsDone(); }
  393. private:
  394. GpPathPointIterator *_iterator;
  395. };
  396. #endif