Source code of Windows XP (NT5)
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.

1413 lines
35 KiB

  1. // xutility internal header
  2. #pragma once
  3. #ifndef _XUTILITY_
  4. #define _XUTILITY_
  5. #include <climits>
  6. #include <utility>
  7. #pragma pack(push,8)
  8. #pragma warning(push,3)
  9. #pragma warning(disable:4786)
  10. _STD_BEGIN
  11. // ITERATOR STUFF (from <iterator>)
  12. // ITERATOR TAGS
  13. struct input_iterator_tag
  14. { // identifying tag for input iterators
  15. };
  16. struct output_iterator_tag
  17. { // identifying tag for output iterators
  18. };
  19. struct forward_iterator_tag
  20. : public input_iterator_tag
  21. { // identifying tag for forward iterators
  22. };
  23. struct bidirectional_iterator_tag
  24. : public forward_iterator_tag
  25. { // identifying tag for bidirectional iterators
  26. };
  27. struct random_access_iterator_tag
  28. : public bidirectional_iterator_tag
  29. { // identifying tag for random-access iterators
  30. };
  31. struct _Int_iterator_tag
  32. { // identifying tag for integer types, not an iterator
  33. };
  34. // POINTER ITERATOR TAGS
  35. struct _Nonscalar_ptr_iterator_tag
  36. { // pointer to unknown type
  37. };
  38. struct _Scalar_ptr_iterator_tag
  39. { // pointer to scalar type
  40. };
  41. // TEMPLATE CLASS iterator
  42. template<class _Category,
  43. class _Ty,
  44. class _Diff = ptrdiff_t,
  45. class _Pointer = _Ty *,
  46. class _Reference = _Ty&>
  47. struct iterator
  48. { // base type for all iterator classes
  49. typedef _Category iterator_category;
  50. typedef _Ty value_type;
  51. typedef _Diff difference_type;
  52. typedef _Diff distance_type; // retained
  53. typedef _Pointer pointer;
  54. typedef _Reference reference;
  55. };
  56. template<class _Ty,
  57. class _Diff,
  58. class _Pointer,
  59. class _Reference>
  60. struct _Bidit
  61. : public iterator<bidirectional_iterator_tag, _Ty, _Diff,
  62. _Pointer, _Reference>
  63. { // base for bidirectional iterators
  64. };
  65. template<class _Ty,
  66. class _Diff,
  67. class _Pointer,
  68. class _Reference>
  69. struct _Ranit
  70. : public iterator<random_access_iterator_tag, _Ty, _Diff,
  71. _Pointer, _Reference>
  72. { // base for random-access iterators
  73. };
  74. struct _Outit
  75. : public iterator<output_iterator_tag, void, void,
  76. void, void>
  77. { // base for output iterators
  78. };
  79. // TEMPLATE CLASS iterator_traits
  80. template<class _Iter>
  81. struct iterator_traits
  82. { // get traits from iterator _Iter
  83. typedef typename _Iter::iterator_category iterator_category;
  84. typedef typename _Iter::value_type value_type;
  85. typedef typename _Iter::difference_type difference_type;
  86. typedef difference_type distance_type; // retained
  87. typedef typename _Iter::pointer pointer;
  88. typedef typename _Iter::reference reference;
  89. };
  90. // TEMPLATE FUNCTION _Iter_cat
  91. template<class _Category,
  92. class _Ty,
  93. class _Diff,
  94. class _Pointer,
  95. class _Reference> inline
  96. _Category _Iter_cat(const iterator<_Category, _Ty, _Diff,
  97. _Pointer, _Reference>&)
  98. { // return category from iterator argument
  99. _Category _Cat;
  100. return (_Cat);
  101. }
  102. template<class _Ty> inline
  103. random_access_iterator_tag _Iter_cat(const _Ty *)
  104. { // return category from pointer argument
  105. random_access_iterator_tag _Cat;
  106. return (_Cat);
  107. }
  108. // INTEGER FUNCTION _Iter_cat
  109. inline _Int_iterator_tag _Iter_cat(_Bool)
  110. { // return category from bool argument
  111. _Int_iterator_tag _Cat;
  112. return (_Cat);
  113. }
  114. inline _Int_iterator_tag _Iter_cat(char)
  115. { // return category from char argument
  116. _Int_iterator_tag _Cat;
  117. return (_Cat);
  118. }
  119. inline _Int_iterator_tag _Iter_cat(signed char)
  120. { // return category from signed char argument
  121. _Int_iterator_tag _Cat;
  122. return (_Cat);
  123. }
  124. inline _Int_iterator_tag _Iter_cat(unsigned char)
  125. { // return category from unsigned char argument
  126. _Int_iterator_tag _Cat;
  127. return (_Cat);
  128. }
  129. inline _Int_iterator_tag _Iter_cat(short)
  130. { // return category from short argument
  131. _Int_iterator_tag _Cat;
  132. return (_Cat);
  133. }
  134. inline _Int_iterator_tag _Iter_cat(unsigned short)
  135. { // return category from unsigned short argument
  136. _Int_iterator_tag _Cat;
  137. return (_Cat);
  138. }
  139. inline _Int_iterator_tag _Iter_cat(int)
  140. { // return category from int argument
  141. _Int_iterator_tag _Cat;
  142. return (_Cat);
  143. }
  144. inline _Int_iterator_tag _Iter_cat(unsigned int)
  145. { // return category from unsigned int argument
  146. _Int_iterator_tag _Cat;
  147. return (_Cat);
  148. }
  149. inline _Int_iterator_tag _Iter_cat(long)
  150. { // return category from long argument
  151. _Int_iterator_tag _Cat;
  152. return (_Cat);
  153. }
  154. inline _Int_iterator_tag _Iter_cat(unsigned long)
  155. { // return category from unsigned long argument
  156. _Int_iterator_tag _Cat;
  157. return (_Cat);
  158. }
  159. #ifdef _LONGLONG
  160. inline _Int_iterator_tag _Iter_cat(_LONGLONG)
  161. { // return category from long long argument
  162. _Int_iterator_tag _Cat;
  163. return (_Cat);
  164. }
  165. inline _Int_iterator_tag _Iter_cat(_ULONGLONG)
  166. { // return category from ulong long argument
  167. _Int_iterator_tag _Cat;
  168. return (_Cat);
  169. }
  170. #endif /* _LONGLONG */
  171. // TEMPLATE FUNCTION _Ptr_cat
  172. template<class _T1,
  173. class _T2> inline
  174. _Nonscalar_ptr_iterator_tag _Ptr_cat(const _T1&, _T2&)
  175. { // return pointer category from arbitrary arguments
  176. _Nonscalar_ptr_iterator_tag _Cat;
  177. return (_Cat);
  178. }
  179. #if _HAS_TEMPLATE_PARTIAL_ORDERING
  180. template<class _Ty> inline
  181. _Scalar_ptr_iterator_tag _Ptr_cat(const _Ty **, const _Ty **)
  182. { // return pointer category from pointer to pointer arguments
  183. _Scalar_ptr_iterator_tag _Cat;
  184. return (_Cat);
  185. }
  186. template<class _Ty> inline
  187. _Scalar_ptr_iterator_tag _Ptr_cat(const _Ty *const *, const _Ty **)
  188. { // return pointer category from pointer to pointer arguments
  189. _Scalar_ptr_iterator_tag _Cat;
  190. return (_Cat);
  191. }
  192. #endif /* _HAS_TEMPLATE_PARTIAL_ORDERING */
  193. // INTEGER FUNCTION _Ptr_cat
  194. inline _Scalar_ptr_iterator_tag _Ptr_cat(const _Bool *, _Bool *)
  195. { // return pointer category from pointer to bool arguments
  196. _Scalar_ptr_iterator_tag _Cat;
  197. return (_Cat);
  198. }
  199. inline _Scalar_ptr_iterator_tag _Ptr_cat(const char *, char *)
  200. { // return pointer category from pointer to char arguments
  201. _Scalar_ptr_iterator_tag _Cat;
  202. return (_Cat);
  203. }
  204. inline _Scalar_ptr_iterator_tag _Ptr_cat(const signed char *, signed char *)
  205. { // return pointer category from pointer to signed char arguments
  206. _Scalar_ptr_iterator_tag _Cat;
  207. return (_Cat);
  208. }
  209. inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned char *,
  210. unsigned char *)
  211. { // return pointer category from pointer to unsigned char arguments
  212. _Scalar_ptr_iterator_tag _Cat;
  213. return (_Cat);
  214. }
  215. inline _Scalar_ptr_iterator_tag _Ptr_cat(const short *, short *)
  216. { // return pointer category from pointer to short arguments
  217. _Scalar_ptr_iterator_tag _Cat;
  218. return (_Cat);
  219. }
  220. inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned short *,
  221. unsigned short *)
  222. { // return pointer category from pointer to unsigned short arguments
  223. _Scalar_ptr_iterator_tag _Cat;
  224. return (_Cat);
  225. }
  226. inline _Scalar_ptr_iterator_tag _Ptr_cat(const int *, int *)
  227. { // return pointer category from pointer to int arguments
  228. _Scalar_ptr_iterator_tag _Cat;
  229. return (_Cat);
  230. }
  231. inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned int *, unsigned int *)
  232. { // return pointer category from pointer to unsigned int arguments
  233. _Scalar_ptr_iterator_tag _Cat;
  234. return (_Cat);
  235. }
  236. inline _Scalar_ptr_iterator_tag _Ptr_cat(const long *, long *)
  237. { // return pointer category from pointer to long arguments
  238. _Scalar_ptr_iterator_tag _Cat;
  239. return (_Cat);
  240. }
  241. inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned long *,
  242. unsigned long *)
  243. { // return pointer category from pointer to unsigned long arguments
  244. _Scalar_ptr_iterator_tag _Cat;
  245. return (_Cat);
  246. }
  247. inline _Scalar_ptr_iterator_tag _Ptr_cat(const float *, float *)
  248. { // return pointer category from pointer to float arguments
  249. _Scalar_ptr_iterator_tag _Cat;
  250. return (_Cat);
  251. }
  252. inline _Scalar_ptr_iterator_tag _Ptr_cat(const double *, double *)
  253. { // return pointer category from pointer to double arguments
  254. _Scalar_ptr_iterator_tag _Cat;
  255. return (_Cat);
  256. }
  257. inline _Scalar_ptr_iterator_tag _Ptr_cat(const long double *, long double *)
  258. { // return pointer category from pointer to long double arguments
  259. _Scalar_ptr_iterator_tag _Cat;
  260. return (_Cat);
  261. }
  262. #ifdef _LONGLONG
  263. inline _Scalar_ptr_iterator_tag _Ptr_cat(const _LONGLONG *, _LONGLONG *)
  264. { // return pointer category from pointer to long long arguments
  265. _Scalar_ptr_iterator_tag _Cat;
  266. return (_Cat);
  267. }
  268. inline _Scalar_ptr_iterator_tag _Ptr_cat(const _ULONGLONG *, _ULONGLONG *)
  269. { // return pointer category from pointer to ulong long arguments
  270. _Scalar_ptr_iterator_tag _Cat;
  271. return (_Cat);
  272. }
  273. #endif /* _LONGLONG */
  274. // TEMPLATE FUNCTIONS distance and _Distance
  275. template<class _InIt> inline
  276. ptrdiff_t distance(_InIt _First, _InIt _Last)
  277. { // return distance between iterators
  278. ptrdiff_t _Off = 0;
  279. _Distance2(_First, _Last, _Off, _Iter_cat(_First));
  280. return (_Off);
  281. }
  282. template<class _InIt,
  283. class _Diff> inline
  284. void _Distance(_InIt _First, _InIt _Last, _Diff& _Off)
  285. { // add to _Off distance between iterators
  286. _Distance2(_First, _Last, _Off, _Iter_cat(_First));
  287. }
  288. template<class _InIt,
  289. class _Diff> inline
  290. void _Distance2(_InIt _First, _InIt _Last, _Diff& _Off,
  291. input_iterator_tag)
  292. { // add to _Off distance between input iterators
  293. for (; _First != _Last; ++_First)
  294. ++_Off;
  295. }
  296. template<class _FwdIt,
  297. class _Diff> inline
  298. void _Distance2(_FwdIt _First, _FwdIt _Last, _Diff& _Off,
  299. forward_iterator_tag)
  300. { // add to _Off distance between forward iterators (redundant)
  301. for (; _First != _Last; ++_First)
  302. ++_Off;
  303. }
  304. template<class _BidIt,
  305. class _Diff> inline
  306. void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off,
  307. bidirectional_iterator_tag)
  308. { // add to _Off distance between bidirectional iterators (redundant)
  309. for (; _First != _Last; ++_First)
  310. ++_Off;
  311. }
  312. template<class _RanIt,
  313. class _Diff> inline
  314. void _Distance2(_RanIt _First, _RanIt _Last, _Diff& _Off,
  315. random_access_iterator_tag)
  316. { // add to _Off distance between random-access iterators
  317. _Off += _Last - _First;
  318. }
  319. // TEMPLATE CLASS _Ptrit
  320. template<class _Ty,
  321. class _Diff,
  322. class _Pointer,
  323. class _Reference,
  324. class _Pointer2,
  325. class _Reference2>
  326. class _Ptrit
  327. : public _Ranit<_Ty, _Diff, _Pointer, _Reference>
  328. { // wrap pointer as random-access iterator
  329. public:
  330. typedef _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  331. _Pointer2, _Reference2> _Myt;
  332. _Ptrit()
  333. { // construct with uninitialized wrapped pointer
  334. }
  335. _Ptrit(_Pointer _Ptr)
  336. : current(_Ptr)
  337. { // construct wrapped pointer from _Ptr
  338. }
  339. _Ptrit(const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  340. _Pointer2, _Reference2>& _Iter)
  341. : current(_Iter.base())
  342. { // const converter or copy constructor
  343. }
  344. _Pointer base() const
  345. { // return wrapped pointer
  346. return (current);
  347. }
  348. _Reference operator*() const
  349. { // return designated value
  350. return (*current);
  351. }
  352. _Pointer operator->() const
  353. { // return pointer to class object
  354. return (&**this);
  355. }
  356. _Myt& operator++()
  357. { // preincrement
  358. ++current;
  359. return (*this);
  360. }
  361. _Myt operator++(int)
  362. { // postincrement
  363. _Myt _Tmp = *this;
  364. ++current;
  365. return (_Tmp);
  366. }
  367. _Myt& operator--()
  368. { // predecrement
  369. --current;
  370. return (*this);
  371. }
  372. _Myt operator--(int)
  373. { // postdecrement
  374. _Myt _Tmp = *this;
  375. --current;
  376. return (_Tmp);
  377. }
  378. bool operator==(int _Right) const
  379. { // test if wrapped pointer == integer (null pointer constant)
  380. return (current == (_Pointer)_Right);
  381. }
  382. bool operator==(const _Myt& _Right) const
  383. { // test for iterator equality
  384. return (current == _Right.current);
  385. }
  386. bool operator!=(const _Myt& _Right) const
  387. { // test for iterator inequality
  388. return (!(*this == _Right));
  389. }
  390. _Myt& operator+=(_Diff _Off)
  391. { // increment by integer
  392. current += _Off;
  393. return (*this);
  394. }
  395. _Myt operator+(_Diff _Off) const
  396. { // return this + integer
  397. return (_Myt(current + _Off));
  398. }
  399. _Myt& operator-=(_Diff _Off)
  400. { // decrement by integer
  401. current -= _Off;
  402. return (*this);
  403. }
  404. _Myt operator-(_Diff _Off) const
  405. { // return this - integer
  406. return (_Myt(current - _Off));
  407. }
  408. _Reference operator[](_Diff _Off) const
  409. { // subscript
  410. return (*(*this + _Off));
  411. }
  412. bool operator<(const _Myt& _Right) const
  413. { // test if this < _Right
  414. return (current < _Right.current);
  415. }
  416. bool operator>(const _Myt& _Right) const
  417. { // test if this > _Right
  418. return (_Right < *this);
  419. }
  420. bool operator<=(const _Myt& _Right) const
  421. { // test if this <= _Right
  422. return (!(_Right < *this));
  423. }
  424. bool operator>=(const _Myt& _Right) const
  425. { // test if this >= _Right
  426. return (!(*this < _Right));
  427. }
  428. _Diff operator-(const _Myt& _Right) const
  429. { // return difference of iterators
  430. return (current - _Right.current);
  431. }
  432. protected:
  433. _Pointer current; // the wrapped pointer
  434. };
  435. // _Ptrit TEMPLATE FUNCTIONS
  436. template<class _Ty,
  437. class _Diff,
  438. class _Pointer,
  439. class _Reference,
  440. class _Pointer2,
  441. class _Reference2> inline
  442. _Ptrit<_Ty, _Diff, _Pointer, _Reference, _Pointer2, _Reference2>
  443. __cdecl operator+(_Diff _Off,
  444. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  445. _Pointer2, _Reference2>& _Right)
  446. { // return iterator + integer
  447. return (_Right + _Off);
  448. }
  449. template<class _Ty,
  450. class _Diff,
  451. class _Pointer,
  452. class _Reference,
  453. class _Pointer2,
  454. class _Reference2> inline
  455. bool __cdecl operator==(
  456. const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  457. _Pointer2, _Reference2>& _Left,
  458. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  459. _Pointer2, _Reference2>& _Right)
  460. { // test for _Ptrit<non-const *> == _Ptrit<const *>
  461. return (_Right == _Left);
  462. }
  463. template<class _Ty,
  464. class _Diff,
  465. class _Pointer,
  466. class _Reference,
  467. class _Pointer2,
  468. class _Reference2> inline
  469. bool __cdecl operator!=(
  470. const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  471. _Pointer2, _Reference2>& _Left,
  472. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  473. _Pointer2, _Reference2>& _Right)
  474. { // test for _Ptrit<non-const *> != _Ptrit<const *>
  475. return (_Right != _Left);
  476. }
  477. template<class _Ty,
  478. class _Diff,
  479. class _Pointer,
  480. class _Reference,
  481. class _Pointer2,
  482. class _Reference2> inline
  483. bool __cdecl operator<(
  484. const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  485. _Pointer2, _Reference2>& _Left,
  486. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  487. _Pointer2, _Reference2>& _Right)
  488. { // test for _Ptrit<non-const *> < _Ptrit<const *>
  489. return (_Right > _Left);
  490. }
  491. template<class _Ty,
  492. class _Diff,
  493. class _Pointer,
  494. class _Reference,
  495. class _Pointer2,
  496. class _Reference2> inline
  497. bool __cdecl operator>(
  498. const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  499. _Pointer2, _Reference2>& _Left,
  500. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  501. _Pointer2, _Reference2>& _Right)
  502. { // test for _Ptrit<non-const *> > _Ptrit<const *>
  503. return (_Right < _Left);
  504. }
  505. template<class _Ty,
  506. class _Diff,
  507. class _Pointer,
  508. class _Reference,
  509. class _Pointer2,
  510. class _Reference2> inline
  511. bool __cdecl operator<=(
  512. const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  513. _Pointer2, _Reference2>& _Left,
  514. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  515. _Pointer2, _Reference2>& _Right)
  516. { // test for _Ptrit<non-const *> <= _Ptrit<const *>
  517. return (_Right >= _Left);
  518. }
  519. template<class _Ty,
  520. class _Diff,
  521. class _Pointer,
  522. class _Reference,
  523. class _Pointer2,
  524. class _Reference2> inline
  525. bool __cdecl operator>=(
  526. const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
  527. _Pointer2, _Reference2>& _Left,
  528. const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
  529. _Pointer2, _Reference2>& _Right)
  530. { // test for _Ptrit<non-const *> >= _Ptrit<const *>
  531. return (_Right <= _Left);
  532. }
  533. // TEMPLATE CLASS reverse_iterator
  534. template<class _RanIt>
  535. class reverse_iterator
  536. : public iterator<
  537. typename iterator_traits<_RanIt>::iterator_category,
  538. typename iterator_traits<_RanIt>::value_type,
  539. typename iterator_traits<_RanIt>::difference_type,
  540. typename iterator_traits<_RanIt>::pointer,
  541. typename iterator_traits<_RanIt>::reference>
  542. { // wrap iterator to run it backwards
  543. public:
  544. typedef reverse_iterator<_RanIt> _Myt;
  545. typedef typename iterator_traits<_RanIt>::difference_type difference_type;
  546. typedef typename iterator_traits<_RanIt>::pointer pointer;
  547. typedef typename iterator_traits<_RanIt>::reference reference;
  548. typedef _RanIt iterator_type;
  549. reverse_iterator()
  550. { // construct with default wrapped iterator
  551. }
  552. explicit reverse_iterator(_RanIt _Right)
  553. : current(_Right)
  554. { // construct wrapped iterator from _Right
  555. }
  556. template<class _Other>
  557. reverse_iterator(const reverse_iterator<_Other>& _Right)
  558. : current(_Right.base())
  559. { // initialize with compatible base
  560. }
  561. _RanIt base() const
  562. { // return wrapped iterator
  563. return (current);
  564. }
  565. reference operator*() const
  566. { // return designated value
  567. _RanIt _Tmp = current;
  568. return (*--_Tmp);
  569. }
  570. pointer operator->() const
  571. { // return pointer to class object
  572. return (&**this);
  573. }
  574. _Myt& operator++()
  575. { // preincrement
  576. --current;
  577. return (*this);
  578. }
  579. _Myt operator++(int)
  580. { // postincrement
  581. _Myt _Tmp = *this;
  582. --current;
  583. return (_Tmp);
  584. }
  585. _Myt& operator--()
  586. { // predecrement
  587. ++current;
  588. return (*this);
  589. }
  590. _Myt operator--(int)
  591. { // postdecrement
  592. _Myt _Tmp = *this;
  593. ++current;
  594. return (_Tmp);
  595. }
  596. bool _Equal(const _Myt& _Right) const
  597. { // test for iterator equality
  598. return (current == _Right.current);
  599. }
  600. // N.B. functions valid for random-access iterators only beyond this point
  601. _Myt& operator+=(difference_type _Off)
  602. { // increment by integer
  603. current -= _Off;
  604. return (*this);
  605. }
  606. _Myt operator+(difference_type _Off) const
  607. { // return this + integer
  608. return (_Myt(current - _Off));
  609. }
  610. _Myt& operator-=(difference_type _Off)
  611. { // decrement by integer
  612. current += _Off;
  613. return (*this);
  614. }
  615. _Myt operator-(difference_type _Off) const
  616. { // return this - integer
  617. return (_Myt(current + _Off));
  618. }
  619. reference operator[](difference_type _Off) const
  620. { // subscript
  621. return (*(*this + _Off));
  622. }
  623. bool _Less(const _Myt& _Right) const
  624. { // test if this < _Right
  625. return (_Right.current < current);
  626. }
  627. difference_type _Minus(const _Myt& _Right) const
  628. { // return difference of iterators
  629. return (_Right.current - current);
  630. }
  631. protected:
  632. _RanIt current; // the wrapped iterator
  633. };
  634. // reverse_iterator TEMPLATE OPERATORS
  635. template<class _RanIt,
  636. class _Diff> inline
  637. reverse_iterator<_RanIt> __cdecl operator+(_Diff _Off,
  638. const reverse_iterator<_RanIt>& _Right)
  639. { // return reverse_iterator + integer
  640. return (_Right + _Off);
  641. }
  642. template<class _RanIt> inline
  643. size_t __cdecl operator-(const reverse_iterator<_RanIt>& _Left,
  644. const reverse_iterator<_RanIt>& _Right)
  645. { // return difference of reverse_iterators
  646. return (_Left._Minus(_Right));
  647. }
  648. template<class _RanIt> inline
  649. bool __cdecl operator==(const reverse_iterator<_RanIt>& _Left,
  650. const reverse_iterator<_RanIt>& _Right)
  651. { // test for reverse_iterator equality
  652. return (_Left._Equal(_Right));
  653. }
  654. template<class _RanIt> inline
  655. bool __cdecl operator!=(const reverse_iterator<_RanIt>& _Left,
  656. const reverse_iterator<_RanIt>& _Right)
  657. { // test for reverse_iterator inequality
  658. return (!(_Left == _Right));
  659. }
  660. template<class _RanIt> inline
  661. bool __cdecl operator<(const reverse_iterator<_RanIt>& _Left,
  662. const reverse_iterator<_RanIt>& _Right)
  663. { // test for reverse_iterator < reverse_iterator
  664. return (_Left._Less(_Right));
  665. }
  666. template<class _RanIt> inline
  667. bool __cdecl operator>(const reverse_iterator<_RanIt>& _Left,
  668. const reverse_iterator<_RanIt>& _Right)
  669. { // test for reverse_iterator > reverse_iterator
  670. return (_Right < _Left);
  671. }
  672. template<class _RanIt> inline
  673. bool __cdecl operator<=(const reverse_iterator<_RanIt>& _Left,
  674. const reverse_iterator<_RanIt>& _Right)
  675. { // test for reverse_iterator <= reverse_iterator
  676. return (!(_Right < _Left));
  677. }
  678. template<class _RanIt> inline
  679. bool __cdecl operator>=(const reverse_iterator<_RanIt>& _Left,
  680. const reverse_iterator<_RanIt>& _Right)
  681. { // test for reverse_iterator >= reverse_iterator
  682. return (!(_Left < _Right));
  683. }
  684. // TEMPLATE CLASS reverse_bidirectional_iterator (retained)
  685. template<class _BidIt,
  686. class _Ty,
  687. class _Reference = _Ty&,
  688. class _Pointer = _Ty *,
  689. class _Diff = ptrdiff_t>
  690. class reverse_bidirectional_iterator
  691. : public _Bidit<_Ty, _Diff, _Pointer, _Reference>
  692. { // wrap bidirectional iterator to run it backwards
  693. public:
  694. typedef reverse_bidirectional_iterator<_BidIt, _Ty, _Reference,
  695. _Pointer, _Diff> _Myt;
  696. typedef _BidIt iterator_type;
  697. reverse_bidirectional_iterator()
  698. { // construct with default wrapped iterator
  699. }
  700. explicit reverse_bidirectional_iterator(_BidIt _Right)
  701. : current(_Right)
  702. { // construct wrapped iterator from _Right
  703. }
  704. _BidIt base() const
  705. { // return wrapped iterator
  706. return (current);
  707. }
  708. _Reference operator*() const
  709. { // return designated value
  710. _BidIt _Tmp = current;
  711. return (*--_Tmp);
  712. }
  713. _Pointer operator->() const
  714. { // return pointer to class object
  715. _Reference _Tmp = **this;
  716. return (&_Tmp);
  717. }
  718. _Myt& operator++()
  719. { // preincrement
  720. --current;
  721. return (*this);
  722. }
  723. _Myt operator++(int)
  724. { // postincrement
  725. _Myt _Tmp = *this;
  726. --current;
  727. return (_Tmp);
  728. }
  729. _Myt& operator--()
  730. { // predecrement
  731. ++current;
  732. return (*this);
  733. }
  734. _Myt operator--(int)
  735. { // postdecrement
  736. _Myt _Tmp = *this;
  737. ++current;
  738. return (_Tmp);
  739. }
  740. bool operator==(const _Myt& _Right) const
  741. { // test for iterator equality
  742. return (current == _Right.current);
  743. }
  744. bool operator!=(const _Myt& _Right) const
  745. { // test for iterator inequality
  746. return (!(*this == _Right));
  747. }
  748. protected:
  749. _BidIt current; // the wrapped iterator
  750. };
  751. // TEMPLATE CLASS _Revbidit
  752. template<class _BidIt,
  753. class _BidIt2 = _BidIt>
  754. class _Revbidit
  755. : public iterator<
  756. typename iterator_traits<_BidIt>::iterator_category,
  757. typename iterator_traits<_BidIt>::value_type,
  758. typename iterator_traits<_BidIt>::difference_type,
  759. typename iterator_traits<_BidIt>::pointer,
  760. typename iterator_traits<_BidIt>::reference>
  761. { // wrap bidirectional iterator to run it backwards
  762. public:
  763. typedef _Revbidit<_BidIt, _BidIt2> _Myt;
  764. typedef typename iterator_traits<_BidIt>::difference_type _Diff;
  765. typedef typename iterator_traits<_BidIt>::pointer _Pointer;
  766. typedef typename iterator_traits<_BidIt>::reference _Reference;
  767. typedef _BidIt iterator_type;
  768. _Revbidit()
  769. { // construct with default wrapped iterator
  770. }
  771. explicit _Revbidit(_BidIt _Right)
  772. : current(_Right)
  773. { // construct wrapped iterator from _Right
  774. }
  775. _Revbidit(const _Revbidit<_BidIt2>& _Other)
  776. : current (_Other.base())
  777. { // const converter or copy constructor
  778. }
  779. _BidIt base() const
  780. { // return wrapped iterator
  781. return (current);
  782. }
  783. _Reference operator*() const
  784. { // return designated value
  785. _BidIt _Tmp = current;
  786. return (*--_Tmp);
  787. }
  788. _Pointer operator->() const
  789. { // return pointer to class object
  790. _Reference _Tmp = **this;
  791. return (&_Tmp);
  792. }
  793. _Myt& operator++()
  794. { // preincrement
  795. --current;
  796. return (*this);
  797. }
  798. _Myt operator++(int)
  799. { // postincrement
  800. _Myt _Tmp = *this;
  801. --current;
  802. return (_Tmp);
  803. }
  804. _Myt& operator--()
  805. { // predecrement
  806. ++current;
  807. return (*this);
  808. }
  809. _Myt operator--(int)
  810. { // postdecrement
  811. _Myt _Tmp = *this;
  812. ++current;
  813. return (_Tmp);
  814. }
  815. bool operator==(const _Myt& _Right) const
  816. { // test for iterator equality
  817. return (current == _Right.current);
  818. }
  819. bool operator!=(const _Myt& _Right) const
  820. { // test for iterator inequality
  821. return (!(*this == _Right));
  822. }
  823. protected:
  824. _BidIt current;
  825. };
  826. // TEMPLATE CLASS istreambuf_iterator
  827. template<class _Elem,
  828. class _Traits>
  829. class istreambuf_iterator
  830. : public iterator<input_iterator_tag,
  831. _Elem, typename _Traits::off_type, _Elem *, _Elem&>
  832. { // wrap stream buffer as input iterator
  833. public:
  834. typedef istreambuf_iterator<_Elem, _Traits> _Myt;
  835. typedef _Elem char_type;
  836. typedef _Traits traits_type;
  837. typedef basic_streambuf<_Elem, _Traits> streambuf_type;
  838. typedef basic_istream<_Elem, _Traits> istream_type;
  839. typedef typename traits_type::int_type int_type;
  840. istreambuf_iterator(streambuf_type *_Sb = 0) _THROW0()
  841. : _Strbuf(_Sb), _Got(_Sb == 0)
  842. { // construct from stream buffer _Sb
  843. }
  844. istreambuf_iterator(istream_type& _Istr) _THROW0()
  845. : _Strbuf(_Istr.rdbuf()), _Got(_Istr.rdbuf() == 0)
  846. { // construct from stream buffer in istream _Istr
  847. }
  848. _Elem operator*() const
  849. { // return designated value
  850. if (!_Got)
  851. ((_Myt *)this)->_Peek();
  852. return (_Val);
  853. }
  854. _Myt& operator++()
  855. { // preincrement
  856. _Inc();
  857. return (*this);
  858. }
  859. _Myt operator++(int)
  860. { // postincrement
  861. if (!_Got)
  862. _Peek();
  863. _Myt _Tmp = *this;
  864. _Inc();
  865. return (_Tmp);
  866. }
  867. bool equal(const _Myt& _Right) const
  868. { // test for equality
  869. if (!_Got)
  870. ((_Myt *)this)->_Peek();
  871. if (!_Right._Got)
  872. ((_Myt *)&_Right)->_Peek();
  873. return (_Strbuf == 0 && _Right._Strbuf == 0
  874. || _Strbuf != 0 && _Right._Strbuf != 0);
  875. }
  876. private:
  877. void _Inc()
  878. { // skip to next input element
  879. if (_Strbuf == 0
  880. || traits_type::eq_int_type(traits_type::eof(),
  881. _Strbuf->sbumpc()))
  882. _Strbuf = 0, _Got = true;
  883. else
  884. _Got = false;
  885. }
  886. _Elem _Peek()
  887. { // peek at next input element
  888. int_type _Meta;
  889. if (_Strbuf == 0
  890. || traits_type::eq_int_type(traits_type::eof(),
  891. _Meta = _Strbuf->sgetc()))
  892. _Strbuf = 0;
  893. else
  894. _Val = traits_type::to_char_type(_Meta);
  895. _Got = true;
  896. return (_Val);
  897. }
  898. streambuf_type *_Strbuf; // the wrapped stream buffer
  899. bool _Got; // true if _Val is valid
  900. _Elem _Val; // next element to deliver
  901. };
  902. // istreambuf_iterator TEMPLATE OPERATORS
  903. template<class _Elem,
  904. class _Traits> inline
  905. bool __cdecl operator==(
  906. const istreambuf_iterator<_Elem, _Traits>& _Left,
  907. const istreambuf_iterator<_Elem, _Traits>& _Right)
  908. { // test for istreambuf_iterator equality
  909. return (_Left.equal(_Right));
  910. }
  911. template<class _Elem,
  912. class _Traits> inline
  913. bool __cdecl operator!=(
  914. const istreambuf_iterator<_Elem, _Traits>& _Left,
  915. const istreambuf_iterator<_Elem, _Traits>& _Right)
  916. { // test for istreambuf_iterator inequality
  917. return (!(_Left == _Right));
  918. }
  919. // TEMPLATE CLASS ostreambuf_iterator
  920. template<class _Elem,
  921. class _Traits>
  922. class ostreambuf_iterator
  923. : public _Outit
  924. { // wrap stream buffer as output iterator
  925. typedef ostreambuf_iterator<_Elem, _Traits> _Myt;
  926. public:
  927. typedef _Elem char_type;
  928. typedef _Traits traits_type;
  929. typedef basic_streambuf<_Elem, _Traits> streambuf_type;
  930. typedef basic_ostream<_Elem, _Traits> ostream_type;
  931. ostreambuf_iterator(streambuf_type *_Sb) _THROW0()
  932. : _Failed(false), _Strbuf(_Sb)
  933. { // construct from stream buffer _Sb
  934. }
  935. ostreambuf_iterator(ostream_type& _Ostr) _THROW0()
  936. : _Failed(false), _Strbuf(_Ostr.rdbuf())
  937. { // construct from stream buffer in _Ostr
  938. }
  939. _Myt& operator=(_Elem _Right)
  940. { // store element and increment
  941. if (_Strbuf == 0
  942. || traits_type::eq_int_type(_Traits::eof(),
  943. _Strbuf->sputc(_Right)))
  944. _Failed = true;
  945. return (*this);
  946. }
  947. _Myt& operator*()
  948. { // pretend to get designated element
  949. return (*this);
  950. }
  951. _Myt& operator++()
  952. { // pretend to preincrement
  953. return (*this);
  954. }
  955. _Myt& operator++(int)
  956. { // pretend to postincrement
  957. return (*this);
  958. }
  959. bool failed() const _THROW0()
  960. { // return true if any stores failed
  961. return (_Failed);
  962. }
  963. private:
  964. bool _Failed; // true if any stores have failed
  965. streambuf_type *_Strbuf; // the wrapped stream buffer
  966. };
  967. // ALGORITHM STUFF (from <algorithm>)
  968. // TEMPLATE FUNCTION copy
  969. template<class _InIt,
  970. class _OutIt> inline
  971. _OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest)
  972. { // copy [_First, _Last) to [_Dest, ...)
  973. return (_Copy_opt(_First, _Last, _Dest, _Ptr_cat(_First, _Dest)));
  974. }
  975. template<class _InIt,
  976. class _OutIt> inline
  977. _OutIt _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest,
  978. _Nonscalar_ptr_iterator_tag)
  979. { // copy [_First, _Last) to [_Dest, ...), arbitrary iterators
  980. for (; _First != _Last; ++_Dest, ++_First)
  981. *_Dest = *_First;
  982. return (_Dest);
  983. }
  984. template<class _InIt,
  985. class _OutIt> inline
  986. _OutIt _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest,
  987. _Scalar_ptr_iterator_tag)
  988. { // copy [_First, _Last) to [_Dest, ...), pointers to scalars
  989. ptrdiff_t _Off = _Last - _First; // NB: non-overlapping move
  990. return ((_OutIt)::memmove(&*_Dest, &*_First,
  991. _Off * sizeof (*_First)) + _Off);
  992. }
  993. // TEMPLATE FUNCTION copy_backward
  994. template<class _BidIt1,
  995. class _BidIt2> inline
  996. _BidIt2 copy_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest)
  997. { // copy [_First, _Last) backwards to [..., _Dest)
  998. return (_Copy_backward_opt(_First, _Last, _Dest,
  999. _Ptr_cat(_First, _Dest)));
  1000. }
  1001. template<class _BidIt1,
  1002. class _BidIt2> inline
  1003. _BidIt2 _Copy_backward_opt(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest,
  1004. _Nonscalar_ptr_iterator_tag)
  1005. { // copy [_First, _Last) backwards to [..., _Dest), arbitrary iterators
  1006. while (_First != _Last)
  1007. *--_Dest = *--_Last;
  1008. return (_Dest);
  1009. }
  1010. template<class _InIt,
  1011. class _OutIt> inline
  1012. _OutIt _Copy_backward_opt(_InIt _First, _InIt _Last, _OutIt _Dest,
  1013. _Scalar_ptr_iterator_tag)
  1014. { // copy [_First, _Last) backwards to [..., _Dest), pointers to scalars
  1015. ptrdiff_t _Off = _Last - _First; // NB: non-overlapping move
  1016. return ((_OutIt)memmove(&*_Dest - _Off, &*_First,
  1017. _Off * sizeof (*_First)));
  1018. }
  1019. // TEMPLATE FUNCTION mismatch
  1020. template<class _InIt1,
  1021. class _InIt2> inline
  1022. pair<_InIt1, _InIt2>
  1023. mismatch(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2)
  1024. { // return [_First1, _Last1) and [_First2, _Last2) mismatch
  1025. for (; _First1 != _Last1 && *_First1 == *_First2; )
  1026. ++_First1, ++_First2;
  1027. return (pair<_InIt1, _InIt2>(_First1, _First2));
  1028. }
  1029. // TEMPLATE FUNCTION mismatch WITH PRED
  1030. template<class _InIt1,
  1031. class _InIt2,
  1032. class _Pr> inline
  1033. pair<_InIt1, _InIt2>
  1034. mismatch(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Pr _Pred)
  1035. { // return [_First1, _Last1) and [_First2, _Last2) mismatch using _Pred
  1036. for (; _First1 != _Last1 && _Pred(*_First1, *_First2); )
  1037. ++_First1, ++_First2;
  1038. return (pair<_InIt1, _InIt2>(_First1, _First2));
  1039. }
  1040. // TEMPLATE FUNCTION equal
  1041. template<class _InIt1,
  1042. class _InIt2> inline
  1043. bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2)
  1044. { // compare [_First1, _Last1) to [First2, ...)
  1045. return (mismatch(_First1, _Last1, _First2).first == _Last1);
  1046. }
  1047. inline bool equal(const char *_First1,
  1048. const char *_Last1, const char *_First2)
  1049. { // compare [_First1, _Last1) to [First2, ...), for chars
  1050. return (::memcmp(_First1, _First2, _Last1 - _First1) == 0);
  1051. }
  1052. inline bool equal(const signed char *_First1,
  1053. const signed char *_Last1, const signed char *_First2)
  1054. { // compare [_First1, _Last1) to [First2, ...), for signed chars
  1055. return (::memcmp(_First1, _First2, _Last1 - _First1) == 0);
  1056. }
  1057. inline bool equal(const unsigned char *_First1,
  1058. const unsigned char *_Last1, const unsigned char *_First2)
  1059. { // compare [_First1, _Last1) to [First2, ...), for unsigned chars
  1060. return (::memcmp(_First1, _First2, _Last1 - _First1) == 0);
  1061. }
  1062. // TEMPLATE FUNCTION equal WITH PRED
  1063. template<class _InIt1,
  1064. class _InIt2,
  1065. class _Pr> inline
  1066. bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Pr _Pred)
  1067. { // compare [_First1, _Last1) to [First2, ...) using _Pred
  1068. return (mismatch(_First1, _Last1, _First2, _Pred).first == _Last1);
  1069. }
  1070. // TEMPLATE FUNCTION fill
  1071. template<class _FwdIt,
  1072. class _Ty> inline
  1073. void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
  1074. { // copy _Val through [_First, _Last)
  1075. for (; _First != _Last; ++_First)
  1076. *_First = _Val;
  1077. }
  1078. inline void fill(char *_First, char *_Last, int _Val)
  1079. { // copy char _Val through [_First, _Last)
  1080. ::memset(_First, _Val, _Last - _First);
  1081. }
  1082. inline void fill(signed char *_First, signed char *_Last, int _Val)
  1083. { // copy signed char _Val through [_First, _Last)
  1084. ::memset(_First, _Val, _Last - _First);
  1085. }
  1086. inline void fill(unsigned char *_First, unsigned char *_Last, int _Val)
  1087. { // copy unsigned char _Val through [_First, _Last)
  1088. ::memset(_First, _Val, _Last - _First);
  1089. }
  1090. // TEMPLATE FUNCTION fill_n
  1091. template<class _OutIt,
  1092. class _Diff,
  1093. class _Ty> inline
  1094. void fill_n(_OutIt _First, _Diff _Count, const _Ty& _Val)
  1095. { // copy _Val _Count times through [_First, ...)
  1096. for (; 0 < _Count; --_Count, ++_First)
  1097. *_First = _Val;
  1098. }
  1099. inline void fill_n(char *_First, size_t _Count, int _Val)
  1100. { // copy char _Val _Count times through [_First, ...)
  1101. ::memset(_First, _Val, _Count);
  1102. }
  1103. inline void fill_n(signed char *_First, size_t _Count, int _Val)
  1104. { // copy signed char _Val _Count times through [_First, ...)
  1105. ::memset(_First, _Val, _Count);
  1106. }
  1107. inline void fill_n(unsigned char *_First, size_t _Count, int _Val)
  1108. { // copy unsigned char _Val _Count times through [_First, ...)
  1109. ::memset(_First, _Val, _Count);
  1110. }
  1111. // TEMPLATE FUNCTION lexicographical_compare
  1112. template<class _InIt1,
  1113. class _InIt2> inline
  1114. bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1,
  1115. _InIt2 _First2, _InIt2 _Last2)
  1116. { // order [_First1, _Last1) vs. [First2, Last2)
  1117. for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2)
  1118. if (*_First1 < *_First2)
  1119. return (true);
  1120. else if (*_First2 < *_First1)
  1121. return (false);
  1122. return (_First1 == _Last1 && _First2 != _Last2);
  1123. }
  1124. inline bool lexicographical_compare(
  1125. const unsigned char *_First1, const unsigned char *_Last1,
  1126. const unsigned char *_First2, const unsigned char *_Last2)
  1127. { // order [_First1, _Last1) vs. [First2, Last2), for unsigned char
  1128. ptrdiff_t _Num1 = _Last1 - _First1;
  1129. ptrdiff_t _Num2 = _Last2 - _First2;
  1130. int _Ans = ::memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2);
  1131. return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2);
  1132. }
  1133. #if CHAR_MAX == UCHAR_MAX
  1134. inline bool lexicographical_compare(
  1135. const char *_First1, const char *_Last1,
  1136. const char *_First2, const char *_Last2)
  1137. { // order [_First1, _Last1) vs. [First2, Last2), for nonnegative char
  1138. ptrdiff_t _Num1 = _Last1 - _First1;
  1139. ptrdiff_t _Num2 = _Last2 - _First2;
  1140. int _Ans = ::memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2);
  1141. return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2);
  1142. }
  1143. #endif
  1144. // TEMPLATE FUNCTION lexicographical_compare WITH PRED
  1145. template<class _InIt1,
  1146. class _InIt2,
  1147. class _Pr> inline
  1148. bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1,
  1149. _InIt2 _First2, _InIt2 _Last2, _Pr _Pred)
  1150. { // order [_First1, _Last1) vs. [First2, Last2) using _Pred
  1151. for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2)
  1152. if (_Pred(*_First1, *_First2))
  1153. return (true);
  1154. else if (_Pred(*_First2, *_First1))
  1155. return (false);
  1156. return (_First1 == _Last1 && _First2 != _Last2);
  1157. }
  1158. #ifndef _MAX /* avoid collision with common (nonconforming) macros */
  1159. #define _MAX (max)
  1160. #define _MIN (min)
  1161. #endif
  1162. // TEMPLATE FUNCTION max
  1163. template<class _Ty> inline
  1164. const _Ty& _MAX(const _Ty& _Left, const _Ty& _Right)
  1165. { // return larger of _Left and _Right
  1166. return (_Left < _Right ? _Right : _Left);
  1167. }
  1168. // TEMPLATE FUNCTION max WITH PRED
  1169. template<class _Ty,
  1170. class _Pr> inline
  1171. const _Ty& _MAX(const _Ty& _Left, const _Ty& _Right, _Pr _Pred)
  1172. { // return larger of _Left and _Right using _Pred
  1173. return (_Pred(_Left, _Right) ? _Right : _Left);
  1174. }
  1175. // TEMPLATE FUNCTION min
  1176. template<class _Ty> inline
  1177. const _Ty& _MIN(const _Ty& _Left, const _Ty& _Right)
  1178. { // return smaller of _Left and _Right
  1179. return (_Right < _Left ? _Right : _Left);
  1180. }
  1181. // TEMPLATE FUNCTION min WITH PRED
  1182. template<class _Ty,
  1183. class _Pr> inline
  1184. const _Ty& _MIN(const _Ty& _Left, const _Ty& _Right, _Pr _Pred)
  1185. { // return smaller of _Left and _Right using _Pred
  1186. return (_Pred(_Right, _Left) ? _Right : _Left);
  1187. }
  1188. #ifndef _cpp_max /* retained from VC++ 6.0 */
  1189. #define _cpp_max max /* retained */
  1190. #define _cpp_min min /* retained */
  1191. #endif
  1192. #pragma warning(default:4786)
  1193. _STD_END
  1194. #pragma warning(pop)
  1195. #pragma pack(pop)
  1196. #endif /* _XUTILITY_ */
  1197. /*
  1198. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  1199. * Consult your license regarding permissions and restrictions.
  1200. */
  1201. /*
  1202. * This file is derived from software bearing the following
  1203. * restrictions:
  1204. *
  1205. * Copyright (c) 1994
  1206. * Hewlett-Packard Company
  1207. *
  1208. * Permission to use, copy, modify, distribute and sell this
  1209. * software and its documentation for any purpose is hereby
  1210. * granted without fee, provided that the above copyright notice
  1211. * appear in all copies and that both that copyright notice and
  1212. * this permission notice appear in supporting documentation.
  1213. * Hewlett-Packard Company makes no representations about the
  1214. * suitability of this software for any purpose. It is provided
  1215. * "as is" without express or implied warranty.
  1216. V3.10:0009 */