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.

757 lines
23 KiB

  1. #if _MSC_VER > 1000
  2. #pragma once
  3. #endif // _MSC_VER > 1000
  4. template< class T, class Allocator= allocator< T> >
  5. class list
  6. {
  7. public: // Types
  8. typedef list< T, Allocator> list_type;
  9. typedef Allocator allocator_type;
  10. typedef typename allocator_type::value_type value_type;
  11. typedef typename allocator_type::pointer pointer;
  12. typedef typename allocator_type::const_pointer const_pointer;
  13. typedef typename allocator_type::reference reference;
  14. typedef typename allocator_type::const_reference const_reference;
  15. typedef typename allocator_type::size_type size_type;
  16. typedef typename allocator_type::difference_type difference_type;
  17. protected: // Types
  18. struct list_node;
  19. typedef typename Allocator::rebind< list_node>::other
  20. list_node_allocator_type;
  21. typedef typename list_node_allocator_type::pointer list_node_pointer;
  22. typedef typename list_node_allocator_type::const_pointer
  23. list_node_const_pointer;
  24. struct list_node
  25. {
  26. list_node_pointer m_pNext;
  27. list_node_pointer m_pPrev;
  28. value_type m_Value;
  29. list_node()
  30. { }
  31. list_node( const value_type& Val): m_Value( Val)
  32. { }
  33. list_node( const list_node_pointer& pN, const list_node_pointer& pP,
  34. const value_type& Val): m_pNext( pN), m_pPrev( pP), m_Value( Val)
  35. { }
  36. ~list_node()
  37. { }
  38. };
  39. public: // Types
  40. class iterator;
  41. class const_iterator;
  42. class reverse_iterator;
  43. class const_reverse_iterator;
  44. friend class iterator;
  45. class iterator
  46. {
  47. public: // Types
  48. typedef bidirectional_iterator_tag iterator_category;
  49. typedef value_type value_type;
  50. typedef difference_type difference_type;
  51. typedef pointer pointer;
  52. typedef reference reference;
  53. friend class const_iterator;
  54. friend class reverse_iterator;
  55. friend class const_reverse_iterator;
  56. friend class list< T, Allocator>;
  57. protected: // Variables
  58. list_node_pointer m_pNode;
  59. public: // Functions
  60. iterator()
  61. { }
  62. explicit iterator( const list_node_pointer& pNode)
  63. :m_pNode( pNode)
  64. { }
  65. iterator( const iterator& Other)
  66. :m_pNode( Other.m_pNode)
  67. { }
  68. iterator( const reverse_iterator& Other)
  69. :m_pNode( Other.m_pNode)
  70. { }
  71. reference operator*() const
  72. { return m_pNode->m_Value; }
  73. pointer operator->() const
  74. { return &m_pNode->m_Value; }
  75. iterator& operator++()
  76. {
  77. m_pNode= m_pNode->m_pNext;
  78. return (*this);
  79. }
  80. iterator operator++(int)
  81. {
  82. iterator Tmp( *this);
  83. ++(*this);
  84. return Tmp;
  85. }
  86. iterator& operator--()
  87. {
  88. m_pNode= m_pNode->m_pPrev;
  89. return (*this);
  90. }
  91. iterator operator--(int)
  92. {
  93. iterator Tmp( *this);
  94. --(*this);
  95. return Tmp;
  96. }
  97. bool operator==( const iterator& Other) const
  98. { return (m_pNode== Other.m_pNode); }
  99. bool operator!=( const iterator& Other) const
  100. { return (m_pNode!= Other.m_pNode); }
  101. };
  102. friend class const_iterator;
  103. class const_iterator
  104. {
  105. public: // Types
  106. typedef bidirectional_iterator_tag iterator_category;
  107. typedef value_type value_type;
  108. typedef difference_type difference_type;
  109. typedef const_pointer pointer;
  110. typedef const_reference reference;
  111. friend class const_reverse_iterator;
  112. friend class list< T, Allocator>;
  113. protected: // Variables
  114. list_node_const_pointer m_pNode;
  115. public: // Functions
  116. const_iterator()
  117. { }
  118. explicit const_iterator( const list_node_const_pointer& pNode)
  119. :m_pNode( pNode)
  120. { }
  121. const_iterator( const iterator& Other)
  122. :m_pNode( Other.m_pNode)
  123. { }
  124. const_iterator( const const_iterator& Other)
  125. :m_pNode( Other.m_pNode)
  126. { }
  127. const_iterator( const reverse_iterator& Other)
  128. :m_pNode( Other.m_pNode)
  129. { }
  130. const_iterator( const const_reverse_iterator& Other)
  131. :m_pNode( Other.m_pNode)
  132. { }
  133. reference operator*() const
  134. { return m_pNode->m_Value; }
  135. pointer operator->() const
  136. { return &m_pNode->m_Value; }
  137. const_iterator& operator++()
  138. {
  139. m_pNode= m_pNode->m_pNext;
  140. return (*this);
  141. }
  142. const_iterator operator++(int)
  143. {
  144. const_iterator Tmp( *this);
  145. ++(*this);
  146. return Tmp;
  147. }
  148. const_iterator& operator--()
  149. {
  150. m_pNode= m_pNode->m_pPrev;
  151. return (*this);
  152. }
  153. const_iterator operator--(int)
  154. {
  155. const_iterator Tmp( *this);
  156. --(*this);
  157. return Tmp;
  158. }
  159. bool operator==( const const_iterator& Other) const
  160. { return (m_pNode== Other.m_pNode); }
  161. bool operator!=( const const_iterator& Other) const
  162. { return (m_pNode!= Other.m_pNode); }
  163. };
  164. friend class reverse_iterator;
  165. class reverse_iterator
  166. {
  167. public: // Types
  168. typedef bidirectional_iterator_tag iterator_category;
  169. typedef value_type value_type;
  170. typedef difference_type difference_type;
  171. typedef pointer pointer;
  172. typedef reference reference;
  173. friend class iterator;
  174. friend class const_iterator;
  175. friend class const_reverse_iterator;
  176. friend class list< T, Allocator>;
  177. protected: // Variables
  178. list_node_pointer m_pNode;
  179. public: // Functions
  180. reverse_iterator()
  181. { }
  182. explicit reverse_iterator( const list_node_pointer& pNode)
  183. :m_pNode( pNode)
  184. { }
  185. reverse_iterator( const iterator& Other)
  186. :m_pNode( Other.m_pNode)
  187. { }
  188. reverse_iterator( const reverse_iterator& Other)
  189. :m_pNode( Other.m_pNode)
  190. { }
  191. reference operator*() const
  192. { return m_pNode->m_Value; }
  193. pointer operator->() const
  194. { return &m_pNode->m_Value; }
  195. reverse_iterator& operator++()
  196. {
  197. m_pNode= m_pNode->m_pPrev;
  198. return (*this);
  199. }
  200. reverse_iterator operator++(int)
  201. {
  202. reverse_iterator Tmp( *this);
  203. ++(*this);
  204. return Tmp;
  205. }
  206. reverse_iterator& operator--()
  207. {
  208. m_pNode= m_pNode->m_pNext;
  209. return (*this);
  210. }
  211. reverse_iterator operator--(int)
  212. {
  213. reverse_iterator Tmp( *this);
  214. --(*this);
  215. return Tmp;
  216. }
  217. bool operator==( const reverse_iterator& Other) const
  218. { return (m_pNode== Other.m_pNode); }
  219. bool operator!=( const reverse_iterator& Other) const
  220. { return (m_pNode!= Other.m_pNode); }
  221. };
  222. friend class const_reverse_iterator;
  223. class const_reverse_iterator
  224. {
  225. public: // Types
  226. typedef bidirectional_iterator_tag iterator_category;
  227. typedef value_type value_type;
  228. typedef difference_type difference_type;
  229. typedef const_pointer pointer;
  230. typedef const_reference reference;
  231. friend class const_iterator;
  232. friend class list< T, Allocator>;
  233. protected: // Variables
  234. list_node_const_pointer m_pNode;
  235. public: // Functions
  236. const_reverse_iterator()
  237. { }
  238. explicit const_reverse_iterator( const list_node_const_pointer& pNode)
  239. :m_pNode( pNode)
  240. { }
  241. const_reverse_iterator( const iterator& Other)
  242. :m_pNode( Other.m_pNode)
  243. { }
  244. const_reverse_iterator( const const_iterator& Other)
  245. :m_pNode( Other.m_pNode)
  246. { }
  247. const_reverse_iterator( const reverse_iterator& Other)
  248. :m_pNode( Other.m_pNode)
  249. { }
  250. const_reverse_iterator( const const_reverse_iterator& Other)
  251. :m_pNode( Other.m_pNode)
  252. { }
  253. reference operator*() const
  254. { return m_pNode->m_Value; }
  255. pointer operator->() const
  256. { return &m_pNode->m_Value; }
  257. const_reverse_iterator& operator++()
  258. {
  259. m_pNode= m_pNode->m_pPrev;
  260. return (*this);
  261. }
  262. const_reverse_iterator operator++(int)
  263. {
  264. const_reverse_iterator Tmp( *this);
  265. ++(*this);
  266. return Tmp;
  267. }
  268. const_reverse_iterator& operator--()
  269. {
  270. m_pNode= m_pNode->m_pNext;
  271. return (*this);
  272. }
  273. const_reverse_iterator operator--(int)
  274. {
  275. const_reverse_iterator Tmp( *this);
  276. --(*this);
  277. return Tmp;
  278. }
  279. bool operator==( const const_reverse_iterator& Other) const
  280. { return (m_pNode== Other.m_pNode); }
  281. bool operator!=( const const_reverse_iterator& Other) const
  282. { return (m_pNode!= Other.m_pNode); }
  283. };
  284. protected: // Variables
  285. list_node_pointer m_pHead;
  286. size_type m_uiNodes;
  287. list_node_allocator_type m_Allocator;
  288. protected: // Functions
  289. void BuildHeadNode()
  290. {
  291. m_pHead= m_Allocator.allocate( 1);
  292. new (&m_pHead->m_pNext) list_node_pointer( m_pHead);
  293. new (&m_pHead->m_pPrev) list_node_pointer( m_pHead);
  294. }
  295. void DestroyHeadNode()
  296. {
  297. m_pHead->m_pNext.~list_node_pointer();
  298. m_pHead->m_pPrev.~list_node_pointer();
  299. m_Allocator.deallocate( m_pHead, 1);
  300. }
  301. public: // Functions
  302. iterator begin()
  303. { return iterator( m_pHead->m_pNext); }
  304. iterator end()
  305. { return iterator( m_pHead); }
  306. reverse_iterator rbegin()
  307. { return reverse_iterator( m_pHead->m_pPrev); }
  308. reverse_iterator rend()
  309. { return reverse_iterator( m_pHead); }
  310. const_iterator begin() const
  311. { return const_iterator( m_pHead->m_pNext); }
  312. const_iterator end() const
  313. { return const_iterator( m_pHead); }
  314. const_reverse_iterator rbegin() const
  315. { return const_reverse_iterator( m_pHead->m_pPrev); }
  316. const_reverse_iterator rend() const
  317. { return const_reverse_iterator( m_pHead->m_pPrev); }
  318. size_type size() const
  319. { return m_uiNodes; }
  320. size_type max_size() const
  321. { return m_Allocator.max_size(); }
  322. bool empty() const
  323. { return (0== m_uiNodes); }
  324. explicit list( const Allocator& A= Allocator())
  325. : m_pHead( NULL), m_uiNodes( 0), m_Allocator( A)
  326. {
  327. BuildHeadNode();
  328. }
  329. explicit list( size_type n, const T& x= T(), const Allocator& A= Allocator())
  330. : m_pHead( NULL), m_uiNodes( 0), m_Allocator( A)
  331. {
  332. BuildHeadNode();
  333. try {
  334. insert( begin(), n, x);
  335. } catch( ... ) {
  336. clear();
  337. DestroyHeadNode();
  338. throw;
  339. }
  340. }
  341. list( const list_type& Other)
  342. : m_pHead( NULL), m_uiNodes( 0), m_Allocator( Other.m_Allocator)
  343. {
  344. BuildHeadNode();
  345. try {
  346. insert( begin(), Other.begin(), Other.end());
  347. } catch( ... ) {
  348. clear();
  349. DestroyHeadNode();
  350. throw;
  351. }
  352. }
  353. template< class InputIterator>
  354. list( InputIterator f, InputIterator l, const Allocator& A= Allocator())
  355. : m_pHead( NULL), m_uiNodes( 0), m_Allocator( Other.m_Allocator)
  356. {
  357. BuildHeadNode();
  358. try {
  359. insert( begin(), f, l);
  360. } catch( ... ) {
  361. clear();
  362. DestroyHeadNode();
  363. throw;
  364. }
  365. }
  366. ~list()
  367. {
  368. clear();
  369. DestroyHeadNode();
  370. }
  371. list_type& operator=( const list_type& Other)
  372. {
  373. if( this!= &Other)
  374. {
  375. // TODO: Better exception handling.
  376. iterator itMyCur( begin());
  377. iterator itMyEnd( end());
  378. const_iterator itOtherCur( Other.begin());
  379. const_iterator itOtherEnd( Other.end());
  380. while( itMyCur!= itMyEnd && itOtherCur!= itOtherEnd)
  381. {
  382. *itMyCur= *itOtherCur;
  383. ++itMyCur;
  384. ++itOtherCur;
  385. }
  386. erase( itMyCur, itMyEnd);
  387. insert( itMyCur, itOtherCur, itOtherEnd);
  388. }
  389. return (*this);
  390. }
  391. allocator_type get_allocator() const
  392. { return m_Allocator; }
  393. void swap( list_type& Other)
  394. {
  395. if( m_Allocator== Other.m_Allocator)
  396. {
  397. swap( m_pHead, Other.m_pHead);
  398. swap( m_uiNodes, Other.m_uiNodes);
  399. }
  400. else
  401. {
  402. iterator itMyCur( begin());
  403. splice( itMyCur, Other);
  404. itMyCur.splice( Other.begin(), *this, itMyCur, end());
  405. }
  406. }
  407. reference front()
  408. { return *begin(); }
  409. const_reference front() const
  410. { return *begin(); }
  411. reference back()
  412. { return *(--end()); }
  413. const_reference back() const
  414. { return *(--end()); }
  415. void push_front( const T& t)
  416. { insert( begin(), t); }
  417. void pop_front()
  418. { erase( begin()); }
  419. void push_back( const T& t)
  420. { insert( end(), t); }
  421. void pop_back()
  422. { erase( --end()); }
  423. iterator insert( iterator pos, const T& t)
  424. {
  425. list_node_pointer pNode( pos.m_pNode);
  426. list_node_pointer pPrev( pNode->m_pPrev);
  427. m_Allocator.construct( pNode->m_pPrev= m_Allocator.allocate( 1),
  428. list_node( pNode, pPrev, t));
  429. pNode= pNode->m_pPrev;
  430. pNode->m_pPrev->m_pNext= pNode;
  431. ++m_uiNodes;
  432. return iterator( pNode);
  433. }
  434. template< class InputIterator>
  435. void insert( iterator pos, InputIterator f, InputIterator l)
  436. {
  437. // TODO: Optimize
  438. while( f!= l)
  439. {
  440. insert( pos, *f);
  441. ++f;
  442. }
  443. }
  444. void insert( iterator pos, size_type n, const T& x)
  445. {
  446. // TODO: Optimize
  447. if( n!= 0) do
  448. {
  449. insert( pos, x);
  450. } while( --n!= 0);
  451. }
  452. iterator erase( iterator pos)
  453. {
  454. list_node_pointer pNode( pos.m_pNode);
  455. list_node_pointer pNext( pNode->m_pNext);
  456. pNode->m_pPrev->m_pNext= pNext;
  457. pNext->m_pPrev= pNode->m_pPrev;
  458. m_Allocator.destroy( pNode);
  459. m_Allocator.deallocate( pNode, 1);
  460. --m_uiNodes;
  461. return iterator( pNext);
  462. }
  463. iterator erase( iterator f, iterator l)
  464. {
  465. // TODO: Optimize
  466. while( f!= l)
  467. {
  468. iterator d( f);
  469. ++f;
  470. erase( d);
  471. }
  472. return f;
  473. }
  474. void clear()
  475. {
  476. if( 0!= size())
  477. {
  478. list_node_pointer pNode( m_pHead->m_pNext);
  479. list_node_pointer pNext( pNode->m_pNext);
  480. do
  481. {
  482. m_Allocator.destroy( pNode);
  483. m_Allocator.deallocate( pNode, 1);
  484. pNode= pNext;
  485. pNext= pNext->m_pNext;
  486. } while( pNode!= m_pHead);
  487. m_pHead->m_pPrev= m_pHead->m_pNext= m_pHead;
  488. }
  489. }
  490. void resize( size_type n, T t= T())
  491. {
  492. const size_type CurSize( m_uiNodes);
  493. if( CurSize< n)
  494. insert( end(), n- CurSize, t);
  495. else if( CurSize> n)
  496. {
  497. iterator itStartRange;
  498. if( n> CurSize/ 2)
  499. {
  500. itStartRange= end();
  501. size_type dist( CurSize- n+ 1);
  502. do {
  503. --itStartRange;
  504. } while( --dist!= 0);
  505. }
  506. else
  507. {
  508. itStartRange= begin();
  509. size_type dist( n);
  510. if( dist!= 0) do {
  511. ++itStartRange;
  512. } while( ++dist!= 0);
  513. }
  514. erase( itStartRange, end());
  515. }
  516. }
  517. template< class InputIterator>
  518. void assign( InputIterator f, InputIterator l)
  519. {
  520. iterator itMyCur( begin());
  521. iterator itMyEnd( end());
  522. while( itMyCur!= itMyEnd && f!= l)
  523. {
  524. *itMyCur= *f;
  525. ++itMyCur;
  526. ++f;
  527. }
  528. erase( itMyCur, itMyEnd);
  529. insert( itMyCur, f, l);
  530. }
  531. void assign( size_type n, const T& x= T())
  532. {
  533. iterator itMyCur( begin());
  534. iterator itMyEnd( end());
  535. while( itMyCur!= itMyEnd && f!= l)
  536. {
  537. *itMyCur= *x;
  538. ++itMyCur;
  539. ++f;
  540. }
  541. erase( itMyCur, itMyEnd);
  542. insert( itMyCur, n, x);
  543. }
  544. /* TODO:
  545. void splice( iterator pos, list_type& x)
  546. {
  547. if( !x.empty())
  548. {
  549. _Splice(_P, _X, _X.begin(), _X.end());
  550. _Size += _X._Size;
  551. _X._Size = 0;
  552. }
  553. }
  554. void splice(iterator _P, _Myt& _X, iterator _F)
  555. {iterator _L = _F;
  556. if (_P != _F && _P != ++_L)
  557. {_Splice(_P, _X, _F, _L);
  558. ++_Size;
  559. --_X._Size; }}
  560. void splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
  561. {if (_F != _L)
  562. {if (&_X != this)
  563. {difference_type _N = 0;
  564. _Distance(_F, _L, _N);
  565. _Size += _N;
  566. _X._Size -= _N; }
  567. _Splice(_P, _X, _F, _L); }}
  568. void remove(const T& _V)
  569. {iterator _L = end();
  570. for (iterator _F = begin(); _F != _L; )
  571. if (*_F == _V)
  572. erase(_F++);
  573. else
  574. ++_F; }
  575. typedef binder2nd<not_equal_to<T> > _Pr1;
  576. void remove_if(_Pr1 _Pr)
  577. {iterator _L = end();
  578. for (iterator _F = begin(); _F != _L; )
  579. if (_Pr(*_F))
  580. erase(_F++);
  581. else
  582. ++_F; }
  583. void unique()
  584. {iterator _F = begin(), _L = end();
  585. if (_F != _L)
  586. for (iterator _M = _F; ++_M != _L; _M = _F)
  587. if (*_F == *_M)
  588. erase(_M);
  589. else
  590. _F = _M; }
  591. typedef not_equal_to<T> _Pr2;
  592. void unique(_Pr2 _Pr)
  593. {iterator _F = begin(), _L = end();
  594. if (_F != _L)
  595. for (iterator _M = _F; ++_M != _L; _M = _F)
  596. if (_Pr(*_F, *_M))
  597. erase(_M);
  598. else
  599. _F = _M; }
  600. void merge(_Myt& _X)
  601. {if (&_X != this)
  602. {iterator _F1 = begin(), _L1 = end();
  603. iterator _F2 = _X.begin(), _L2 = _X.end();
  604. while (_F1 != _L1 && _F2 != _L2)
  605. if (*_F2 < *_F1)
  606. {iterator _Mid2 = _F2;
  607. _Splice(_F1, _X, _F2, ++_Mid2);
  608. _F2 = _Mid2; }
  609. else
  610. ++_F1;
  611. if (_F2 != _L2)
  612. _Splice(_L1, _X, _F2, _L2);
  613. _Size += _X._Size;
  614. _X._Size = 0; }}
  615. typedef greater<T> _Pr3;
  616. void merge(_Myt& _X, _Pr3 _Pr)
  617. {if (&_X != this)
  618. {iterator _F1 = begin(), _L1 = end();
  619. iterator _F2 = _X.begin(), _L2 = _X.end();
  620. while (_F1 != _L1 && _F2 != _L2)
  621. if (_Pr(*_F2, *_F1))
  622. {iterator _Mid2 = _F2;
  623. _Splice(_F1, _X, _F2, ++_Mid2);
  624. _F2 = _Mid2; }
  625. else
  626. ++_F1;
  627. if (_F2 != _L2)
  628. _Splice(_L1, _X, _F2, _L2);
  629. _Size += _X._Size;
  630. _X._Size = 0; }}
  631. void sort()
  632. {if (2 <= size())
  633. {const size_t _MAXN = 15;
  634. _Myt _X(allocator), Allocator[_MAXN + 1];
  635. size_t _N = 0;
  636. while (!empty())
  637. {_X.splice(_X.begin(), *this, begin());
  638. size_t _I;
  639. for (_I = 0; _I < _N && !Allocator[_I].empty(); ++_I)
  640. {Allocator[_I].merge(_X);
  641. Allocator[_I].swap(_X); }
  642. if (_I == _MAXN)
  643. Allocator[_I].merge(_X);
  644. else
  645. {Allocator[_I].swap(_X);
  646. if (_I == _N)
  647. ++_N; }}
  648. while (0 < _N)
  649. merge(Allocator[--_N]); }}
  650. void sort(_Pr3 _Pr)
  651. {if (2 <= size())
  652. {const size_t _MAXN = 15;
  653. _Myt _X(allocator), Allocator[_MAXN + 1];
  654. size_t _N = 0;
  655. while (!empty())
  656. {_X.splice(_X.begin(), *this, begin());
  657. size_t _I;
  658. for (_I = 0; _I < _N && !Allocator[_I].empty(); ++_I)
  659. {Allocator[_I].merge(_X, _Pr);
  660. Allocator[_I].swap(_X); }
  661. if (_I == _MAXN)
  662. Allocator[_I].merge(_X, _Pr);
  663. else
  664. {Allocator[_I].swap(_X);
  665. if (_I == _N)
  666. ++_N; }}
  667. while (0 < _N)
  668. merge(Allocator[--_N], _Pr); }}
  669. void reverse()
  670. {if (2 <= size())
  671. {iterator _L = end();
  672. for (iterator _F = ++begin(); _F != _L; )
  673. {iterator _M = _F;
  674. _Splice(begin(), *this, _M, ++_F); }}}
  675. protected:
  676. _Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
  677. {_Nodeptr _S = (_Nodeptr)allocator._Charalloc(
  678. 1 * sizeof (list_node));
  679. _Acc::_Next(_S) = _Narg != 0 ? _Narg : _S;
  680. _Acc::_Prev(_S) = _Parg != 0 ? _Parg : _S;
  681. return (_S); }
  682. void _Freenode(_Nodeptr _S)
  683. {allocator.deallocate(_S, 1); }
  684. void _Splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
  685. {if (allocator == _X.allocator)
  686. {_Acc::_Next(_Acc::_Prev(_L._Mynode())) =
  687. _P._Mynode();
  688. _Acc::_Next(_Acc::_Prev(_F._Mynode())) =
  689. _L._Mynode();
  690. _Acc::_Next(_Acc::_Prev(_P._Mynode())) =
  691. _F._Mynode();
  692. _Nodeptr _S = _Acc::_Prev(_P._Mynode());
  693. _Acc::_Prev(_P._Mynode()) =
  694. _Acc::_Prev(_L._Mynode());
  695. _Acc::_Prev(_L._Mynode()) =
  696. _Acc::_Prev(_F._Mynode());
  697. _Acc::_Prev(_F._Mynode()) = _S; }
  698. else
  699. {insert(_P, _F, _L);
  700. _X.erase(_F, _L); }}
  701. void _Xran() const
  702. {_THROW(out_of_range, "invalid list<T> subscript"); }
  703. */
  704. };
  705. // list TEMPLATE OPERATORS
  706. template< class T, class Allocator> inline
  707. bool operator==( const list< T, Allocator>& x, const list< T, Allocator>& y)
  708. {
  709. return (x.size()== y.size()&& equal(x.begin(), x.end(), y.begin()));
  710. }
  711. template< class T, class Allocator> inline
  712. bool operator!=( const list< T, Allocator>& x, const list< T, Allocator>& y)
  713. {
  714. return !(x== y);
  715. }
  716. template< class T, class Allocator> inline
  717. bool operator<( const list< T, Allocator>& x, const list< T, Allocator>& y)
  718. {
  719. return lexicographical_compare( x.begin(), x.end(), y.begin(), y.end());
  720. }
  721. template< class T, class Allocator> inline
  722. bool operator>( const list< T, Allocator>& x, const list< T, Allocator>& y)
  723. {
  724. return y< x;
  725. }
  726. template< class T, class Allocator> inline
  727. bool operator<=( const list< T, Allocator>& x, const list< T, Allocator>& y)
  728. {
  729. return !(y< x);
  730. }
  731. template< class T, class Allocator> inline
  732. bool operator>=( const list< T, Allocator>& x, const list< T, Allocator>& y)
  733. {
  734. return !(x< y);
  735. }