fork download
  1. #include <initializer_list>
  2. #include <type_traits>
  3. #include <utility>
  4. #include <memory>
  5. #include <functional>
  6.  
  7. template <typename Allocator, typename... Args>
  8. typename Allocator::pointer allocator_new(Allocator& allocator, Args&&... args)
  9. {
  10. auto dealloc = [&](typename Allocator::pointer p){ std::allocator_traits<Allocator>::deallocate( allocator, p, 1 ); };
  11. std::unique_ptr<typename Allocator::value_type, decltype( dealloc )> node( std::allocator_traits<Allocator>::allocate( allocator, 1 ), dealloc );
  12. std::allocator_traits<Allocator>::construct( allocator, node.get(), std::forward<Args>( args )... );
  13. return node.release();
  14. }
  15.  
  16. template <typename Allocator>
  17. void allocator_delete(Allocator& allocator, typename Allocator::pointer p) noexcept
  18. {
  19. std::allocator_traits<Allocator>::destroy( allocator, p );
  20. std::allocator_traits<Allocator>::deallocate( allocator, p, 1 );
  21. }
  22.  
  23. class ring_node
  24. {
  25. public:
  26. struct linkup_tag {};
  27. ring_node(ring_node* prev, ring_node* next) noexcept
  28. : next_( next ), prev_( prev ) {}
  29. ring_node(ring_node* prev, ring_node* next, linkup_tag ) noexcept
  30. : ring_node( prev, next )
  31. {
  32. prev_->next_ = this;
  33. next_->prev_ = this;
  34. }
  35.  
  36. ring_node(const ring_node&) = delete;
  37. ring_node& operator=(const ring_node&) = delete;
  38.  
  39. ring_node* next() const noexcept { return next_; }
  40. ring_node* prev() const noexcept { return prev_; }
  41.  
  42. friend void link(ring_node* prev, ring_node* next) noexcept
  43. {
  44. next->prev_ = prev;
  45. prev->next_ = next;
  46. }
  47. friend void intersect(ring_node* a, ring_node* b) noexcept
  48. {
  49. ring_node* a_prev = a->prev();
  50. link( b->prev(), a );
  51. link( a_prev, b );
  52. }
  53. friend void flip(ring_node* p) noexcept
  54. {
  55. std::swap( p->prev_, p->next_ );
  56. }
  57. private:
  58. ring_node* next_;
  59. ring_node* prev_;
  60. };
  61.  
  62. template <typename T>
  63. class list_node : public ring_node
  64. {
  65. public:
  66. using type = T;
  67. T data;
  68.  
  69. template <typename... Args>
  70. list_node(ring_node* next, Args&&... args) noexcept( noexcept( T( std::declval<Args>()... ) ) )
  71. : ring_node( next->prev(), next, linkup_tag() ), data( std::forward<Args>( args )... )
  72. {}
  73.  
  74. list_node(const list_node&) = delete;
  75. list_node& operator=(const list_node&) = delete;
  76.  
  77. template <typename Allocator, typename... Args>
  78. static list_node* make(Allocator& alloc, ring_node* next, Args&&... args)
  79. {
  80. return allocator_new( alloc, next, std::forward<Args>( args )... );
  81. }
  82. template <typename Allocator>
  83. static void retire(Allocator& alloc, list_node* node) noexcept
  84. {
  85. link( node->prev(), node->next() );
  86. allocator_delete( alloc, node );
  87. }
  88. };
  89.  
  90. template <typename Allocator>
  91. class list_iterator;
  92. template <typename Allocator>
  93. class const_list_iterator;
  94. template <typename Allocator>
  95. void iter_splice(const_list_iterator<Allocator> pos, const_list_iterator<Allocator> first, const_list_iterator<Allocator> last) noexcept;
  96. template <typename T, typename Allocator>
  97. class list;
  98.  
  99. template <typename Allocator>
  100. class const_list_iterator
  101. {
  102. public:
  103. using value_type = typename std::allocator_traits<Allocator>::value_type::type;
  104. using difference_type = typename std::allocator_traits<Allocator>::template rebind_traits<value_type>::difference_type;
  105. using pointer = const value_type*;
  106. using reference = const value_type&;
  107. using iterator_category = std::bidirectional_iterator_tag;
  108.  
  109.  
  110. friend class list<value_type, typename std::allocator_traits<Allocator>::template rebind_alloc<value_type>>;
  111. friend void iter_splice<>(const_list_iterator pos, const_list_iterator first, const_list_iterator last) noexcept;
  112.  
  113. const_list_iterator() noexcept {}
  114. const value_type& operator*() const noexcept { return static_cast<list_node<value_type>*>( node )->data; }
  115. const value_type* operator->() const noexcept { return &**this; }
  116. const_list_iterator& operator++() noexcept { return node = node->next(), *this; }
  117. const_list_iterator operator++(int) noexcept { auto x = *this; return node = node->next(), x; }
  118. const_list_iterator& operator--() noexcept { return node = node->prev(), *this; }
  119. const_list_iterator operator--(int) noexcept { auto x = *this; return node = node->prev(), x; }
  120.  
  121. friend bool operator==(const_list_iterator a, const_list_iterator b) noexcept { return a.node == b.node; }
  122. friend bool operator!=(const_list_iterator a, const_list_iterator b) noexcept { return !( a == b ); }
  123. protected:
  124. const_list_iterator(ring_node* node) noexcept
  125. : node( node )
  126. {}
  127. ring_node* node;
  128. };
  129.  
  130. template <typename Allocator>
  131. class list_iterator
  132. : public const_list_iterator<Allocator>
  133. {
  134. public:
  135. using value_type = typename std::allocator_traits<Allocator>::value_type::type;
  136. using difference_type = typename std::allocator_traits<Allocator>::template rebind_traits<value_type>::difference_type;
  137. using pointer = value_type*;
  138. using reference = value_type&;
  139. using iterator_category = std::bidirectional_iterator_tag;
  140.  
  141. template <typename, typename> friend class list;
  142. // friend class list<value_type, typename std::allocator_traits<Allocator>::template rebind_alloc<value_type>>;
  143.  
  144. list_iterator() noexcept {}
  145. private:
  146. list_iterator(ring_node* node) noexcept
  147. : const_list_iterator<Allocator>( node )
  148. {}
  149. public:
  150. value_type& operator*() const noexcept { return static_cast<list_node<value_type>*>( this->node )->data; }
  151. value_type* operator->() const noexcept { return &**this; }
  152. list_iterator& operator++() noexcept { return this->node = this->node->next(), *this; }
  153. list_iterator operator++(int) noexcept { auto x = *this; return this->node = this->node->next(), x; }
  154. list_iterator& operator--() noexcept { return this->node = this->node->prev(), *this; }
  155. list_iterator operator--(int) noexcept { auto x = *this; return this->node = this->node->prev(), x; }
  156. };
  157.  
  158. template <typename Allocator>
  159. void iter_splice(const_list_iterator<Allocator> pos, const_list_iterator<Allocator> first, const_list_iterator<Allocator> last) noexcept
  160. {
  161. intersect( pos.node, first.node );
  162. intersect( pos.node, last.node );
  163. }
  164. template <typename Allocator>
  165. void iter_splice(const_list_iterator<Allocator> pos, const_list_iterator<Allocator> i) noexcept
  166. {
  167. iter_splice( pos, i, std::next( i ) );
  168. }
  169.  
  170. template <typename T, typename Allocator = std::allocator<T>>
  171. class list_base : protected std::allocator_traits<Allocator>::template rebind_alloc<list_node<T>>
  172. {
  173. protected:
  174. using node_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<list_node<T>>;
  175. mutable ring_node anchor;
  176.  
  177. explicit list_base(const Allocator& allocator) noexcept
  178. : node_allocator_type( allocator ), anchor( &anchor, &anchor )
  179. {}
  180.  
  181. ~list_base() noexcept
  182. {
  183. for ( ring_node* p = anchor.prev(); p != &anchor; )
  184. {
  185. list_node<T>* q = static_cast<list_node<T>*>( p );
  186. p = p->prev();
  187. allocator_delete<node_allocator_type>( *this, q );
  188. }
  189. }
  190. };
  191.  
  192. template <typename T, typename Allocator = std::allocator<T>>
  193. class list : private list_base<T, Allocator>
  194. {
  195. using base = list_base<T, Allocator>;
  196. using node_type = list_node<T>;
  197. using node_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<node_type>;
  198. public:
  199. // types:
  200. using value_type = T;
  201. using allocator_type = Allocator;
  202. static_assert( std::is_same<T, typename std::allocator_traits<Allocator>::value_type>::value, "Allocator does not match value_type" );
  203. using reference = value_type&;
  204. using const_reference = const value_type&;
  205. using pointer = typename std::allocator_traits<allocator_type>::pointer;
  206. using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
  207. using size_type = typename std::allocator_traits<allocator_type>::size_type;
  208. using difference_type = typename std::allocator_traits<allocator_type>::difference_type;
  209. using iterator = list_iterator<node_allocator_type>;
  210. using const_iterator = const_list_iterator<node_allocator_type>;
  211. using reverse_iterator = std::reverse_iterator<iterator>;
  212. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  213.  
  214. // construct/copy/destroy:
  215. explicit list(const allocator_type& allocator = allocator_type()) noexcept
  216. : base( allocator )
  217. {}
  218. explicit list(size_type n, const value_type& value = value_type(), const allocator_type& allocator = allocator_type())
  219. : list( allocator )
  220. {
  221. while ( n-- )
  222. push_back( value );
  223. }
  224. template <typename InputIterator, typename std::enable_if<!std::is_fundamental<InputIterator>::value, int>::type = 0>
  225. list(InputIterator first, InputIterator last, const allocator_type& allocator = allocator_type())
  226. : list( allocator )
  227. {
  228. for ( ; first != last; ++first )
  229. push_back( *first );
  230. }
  231. list(const list& other)
  232. : list( other.begin(), other.end(), std::allocator_traits<node_allocator_type>::select_on_container_copy_construction( other.node_alloc() ) )
  233. {}
  234. list(list&& other) noexcept
  235. : base( other.node_alloc() )
  236. {
  237. swap( other );
  238. }
  239. list(const list& other, const allocator_type& allocator) noexcept
  240. : list( other.begin(), other.end(), allocator )
  241. {}
  242. list(list&& other, const allocator_type& allocator) noexcept
  243. : list( allocator )
  244. {
  245. swap( other );
  246. }
  247. list(std::initializer_list<T> init_list, const allocator_type& allocator = allocator_type())
  248. : list( init_list.begin(), init_list.end(), allocator )
  249. {}
  250.  
  251. list& operator=(const list& rhs) { return list( rhs ).swap( *this ), *this; }
  252.  
  253. list& operator=(list&& rhs) noexcept { return swap( rhs ), *this; }
  254.  
  255. list& operator=(std::initializer_list<T> init_list) { return assign( init_list ), *this; }
  256.  
  257. template <typename InputIterator, typename std::enable_if<!std::is_fundamental<InputIterator>::value, int>::type = 0>
  258. void assign(InputIterator first, InputIterator last)
  259. {
  260. for ( auto it = begin(); it != end(); ++it )
  261. if ( first == last )
  262. return (void)erase( it, end() );
  263. else
  264. *it = *first++;
  265. insert( end(), first, last );
  266. }
  267. void assign(size_type n, const value_type& value)
  268. {
  269. for ( auto it = begin(); it != end(); ++it )
  270. if ( n-- == 0 )
  271. return (void)erase( it, end() );
  272. else
  273. *it = value;
  274. insert( end(), n, value );
  275. }
  276. void assign(std::initializer_list<T> init) { assign( init.begin(), init.end() ); }
  277.  
  278. allocator_type get_allocator() const noexcept { return node_alloc(); }
  279.  
  280. // iterators:
  281. iterator begin() noexcept { return this->anchor.next(); }
  282. const_iterator begin() const noexcept { return cbegin(); }
  283. const_iterator cbegin() const noexcept { return this->anchor.next(); }
  284. iterator end() noexcept { return &this->anchor; }
  285. const_iterator end() const noexcept { return cend(); }
  286. const_iterator cend() const noexcept { return &this->anchor; }
  287. reverse_iterator rbegin() noexcept { return reverse_iterator( begin() ); }
  288. const_reverse_iterator rbegin() const noexcept { return crbegin(); }
  289. const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator( cbegin() ); }
  290. reverse_iterator rend() noexcept { return reverse_iterator( end() ); }
  291. const_reverse_iterator rend() const noexcept { return crend(); }
  292. const_reverse_iterator crend() const noexcept { return const_reverse_iterator( cend() ); }
  293.  
  294. // 23.3.5.3, capacity:
  295. bool empty() const noexcept { return cbegin() == cend(); }
  296. size_type size() const noexcept { return std::distance( cbegin(), cend() ); }
  297. size_type max_size() const noexcept { return node_alloc().max_size(); }
  298. void resize(size_type n) { return resize( n, value_type() ); }
  299. void resize(size_type n, const value_type& value)
  300. {
  301. for ( auto it = begin(); it != end(); ++it )
  302. if ( n-- == 0 )
  303. return (void)erase( it, end() );
  304. while ( n-- != 0 )
  305. push_back( value );
  306. }
  307.  
  308. // element access:
  309. value_type& front() noexcept { return *begin(); }
  310. const value_type& front() const noexcept { return *begin(); }
  311. value_type& back() noexcept { return *std::prev( end() ); }
  312. const value_type& back() const noexcept { return *std::prev( end() ); }
  313.  
  314. void pop_front() noexcept { erase( begin() ); }
  315. template <typename... Args>
  316. void emplace_front(Args&&... args) { return emplace( cbegin(), std::forward<Args>( args )... ); }
  317. void push_front(const value_type& value) { insert( cbegin(), value ); }
  318. void push_front(value_type&& value) { insert( cbegin(), std::move( value ) ); }
  319. void pop_back() noexcept { erase( std::prev( end() ) ); }
  320. template <typename... Args>
  321. void emplace_back(Args&&... args) { return emplace( cend(), std::forward<Args>( args )... ); }
  322. void push_back(const value_type& value) { insert( cend(), value ); }
  323. void push_back(value_type&& value) { insert( cend(), std::move( value ) ); }
  324.  
  325.  
  326. template <typename... Args>
  327. iterator emplace(const_iterator position, Args&&... args)
  328. {
  329. return node_type::make( node_alloc(), position.node, std::forward<Args>( args )... );
  330. }
  331. iterator insert(const_iterator position, const T& value) { return emplace( position, value ); }
  332. iterator insert(const_iterator position, T&& x) { return emplace( position, std::move( x ) ); }
  333. iterator insert(const_iterator position, size_type n, const T& x)
  334. {
  335. return splice( position--, list( n, x, get_allocator() ) ), position.node->next();
  336. }
  337.  
  338. template <typename InputIterator, typename std::enable_if<!std::is_fundamental<InputIterator>::value, int>::type = 0>
  339. iterator insert(const_iterator position, InputIterator first, InputIterator last)
  340. {
  341. return splice( position--, list( first, last, get_allocator() ) ), position.node->next();
  342. }
  343.  
  344. iterator insert(const_iterator position, std::initializer_list<T> il)
  345. {
  346. return splice( position--, list( il.begin(), il.end(), get_allocator() ) ), position.node.next();
  347. }
  348.  
  349. iterator erase(const_iterator position) noexcept
  350. {
  351. return node_type::retire( node_alloc(), static_cast<node_type*>( position++.node ) ), position.node;
  352. }
  353. iterator erase(const_iterator position, const_iterator last) noexcept
  354. {
  355. return iter_splice( list( get_allocator() ).cend(), position, last ), last.node;
  356. }
  357.  
  358. void swap(list& other) noexcept
  359. {
  360. intersect( &this->anchor, &other.anchor );
  361. intersect( this->anchor.next(), other.anchor.next() );
  362. }
  363. friend void swap(list& a, list& b) noexcept { a.swap( b ); }
  364.  
  365. void clear() noexcept { erase( begin(), end() ); }
  366.  
  367. // 23.3.5.5, list operations:
  368. void splice(const_iterator position, list& x) noexcept { iter_splice( position, x.cbegin(), x.cend() ); }
  369. void splice(const_iterator position, list&& x) noexcept { iter_splice( position, x.cbegin(), x.cend() ); }
  370. void splice(const_iterator position, list& x, const_iterator i) noexcept { iter_splice( position, i ); }
  371. void splice(const_iterator position, list&& x, const_iterator i) noexcept { iter_splice( position, i ); }
  372. void splice(const_iterator position, list& x, const_iterator first, const_iterator last) noexcept { iter_splice( position, first, last ); }
  373. void splice(const_iterator position, list&& x, const_iterator first, const_iterator last) noexcept { iter_splice( position, first, last ); }
  374.  
  375. void remove(const T& value) { remove_if( [&](const T& v) { return v == value; } ); }
  376.  
  377. template <typename Predicate>
  378. void remove_if(Predicate pred) noexcept
  379. {
  380. for ( auto it = begin(); it != end(); )
  381. if ( pred( *it ) )
  382. it = erase( it );
  383. else
  384. ++it;
  385. }
  386.  
  387. void unique() noexcept { unique( std::equal_to<T>() ); }
  388. template <typename BinaryPredicate>
  389. void unique(BinaryPredicate binary_pred) noexcept
  390. {
  391. auto it = cbegin();
  392. if ( it == cend() )
  393. return;
  394. for ( auto it2 = it; ++it2 != cend(); it2 = it )
  395. if ( binary_pred( *it, *it2 ) )
  396. erase( it2 );
  397. else
  398. it = it2;
  399. }
  400.  
  401. void merge(list& x) noexcept { merge( x, std::less<T>() ); }
  402. void merge(list&& x) noexcept { merge( x ); }
  403. template <typename Compare>
  404. void merge(list& x, Compare comp) noexcept
  405. {
  406. auto it = cbegin();
  407. if ( it == cend() )
  408. return splice( it, x );
  409. auto it2 = x.cbegin();
  410. if ( it2 == x.cend() )
  411. return;
  412. for ( ;; )
  413. {
  414. while ( !comp( *it2, *it ) )
  415. if ( ++it == cend() )
  416. return splice( it, x );
  417. iter_splice( it, it2++ );
  418. if ( it2 == x.cend() )
  419. return;
  420. }
  421. }
  422. template <typename Compare>
  423. void merge(list&& x, Compare comp) noexcept { merge( x, comp ); };
  424.  
  425. void reverse() noexcept
  426. {
  427. ring_node* p = const_cast<ring_node*>( &this->anchor );
  428. do {
  429. flip( p );
  430. p = p->next();
  431. } while ( p != &this->anchor );
  432. }
  433.  
  434. void sort() noexcept { sort( std::less<T>() ); }
  435. template <typename Compare>
  436. void sort(Compare comp) noexcept
  437. {
  438. list tmp[64];
  439. list* last = tmp;
  440.  
  441. while ( !empty() )
  442. {
  443. iter_splice( tmp[0].begin(), begin() );
  444. auto p = tmp;
  445. for( ;; ++p )
  446. {
  447. bool empty = p[1].empty();
  448. p[1].merge( p[0] );
  449. if ( empty )
  450. break;
  451. }
  452. if ( p == last )
  453. ++last;
  454. }
  455. while ( last != tmp )
  456. merge( *last-- );
  457. }
  458. private:
  459. node_allocator_type& node_alloc() noexcept { return *this; }
  460. const node_allocator_type& node_alloc() const noexcept { return *this; }
  461. };
  462.  
  463. #include <iostream>
  464. #include <iterator>
  465. #include <algorithm>
  466.  
  467. struct foo_t {
  468.  
  469. unsigned value;
  470.  
  471. foo_t() : value() {}
  472. foo_t( unsigned value ) : value( value ) {}
  473. operator unsigned() const { return value; }
  474.  
  475. void tell() { std::cout << value; }
  476. };
  477.  
  478. int main()
  479. {
  480. // ein paar Tests ...
  481.  
  482. list< foo_t > list_1;
  483.  
  484. for( unsigned i = 0; i < 20; ++i )
  485. list_1.push_back( foo_t( i ) );
  486.  
  487. for( auto it = list_1.begin(); it != list_1.end(); ++it ) {
  488.  
  489. it->tell();
  490. std::cout << " ";
  491. }
  492. std::cout.put( '\n' );
  493.  
  494. list< foo_t > list_2;
  495.  
  496. std::copy( list_1.begin(), list_1.end(), std::back_inserter( list_2 ) );
  497. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  498. std::cout.put( '\n' );
  499.  
  500. std::for_each( std::begin( list_2 ), std::end( list_2 ), []( foo_t &foo ) { foo.value *= 2; } );
  501. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  502. std::cout.put( '\n' );
  503.  
  504. auto list_x = list_1;
  505. auto list_y = list_2;
  506. list_x.merge( list_y );
  507. std::copy( list_x.begin(), list_x.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  508. std::cout.put( '\n' );
  509.  
  510. list_1 = list_2;
  511. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  512. std::cout.put( '\n' );
  513.  
  514. list_1.reverse();
  515. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  516. std::cout.put( '\n' );
  517.  
  518. auto head = list_1.cbegin();
  519. auto tail = list_1.cend();
  520.  
  521. for( unsigned i = 0; i < 3; ++i ) {
  522.  
  523. ++head;
  524. --tail;
  525. }
  526.  
  527. list_1.erase( head, tail );
  528. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  529. std::cout.put( '\n' );
  530.  
  531. list_1.resize( 12, 42 );
  532. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  533. std::cout.put( '\n' );
  534.  
  535. list_1.resize( 7 );
  536. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  537. std::cout.put( '\n' );
  538.  
  539. list_1.erase( list_1.cbegin() );
  540. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  541. std::cout.put( '\n' );
  542.  
  543. list_1.erase( --list_1.cend() );
  544. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  545. std::cout.put( '\n' );
  546.  
  547. auto it = list_2.begin();
  548. while( it != list_2.end() ) {
  549.  
  550. if( *it > 15 )
  551. it = list_2.erase( it );
  552. else
  553. ++it;
  554. }
  555. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  556. std::cout.put( '\n' );
  557.  
  558. std::vector< foo_t > vec( list_2.cbegin(), list_2.cend() );
  559. std::copy( vec.begin(), vec.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  560. std::cout.put( '\n' );
  561.  
  562. list_2.insert( ++list_2.cbegin(), 1 );
  563. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  564. std::cout.put( '\n' );
  565.  
  566. list_2.insert( --list_2.cend(), 13 );
  567. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  568. std::cout.put( '\n' );
  569.  
  570. list_2.insert( list_2.cbegin(), 4, foo_t( 42 ) );
  571. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  572. std::cout.put( '\n' );
  573.  
  574. list_2.insert( list_2.cend(), 4, foo_t( 42 ) );
  575. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  576. std::cout.put( '\n' );
  577.  
  578. list_2.insert( ++list_2.cbegin(), 3, foo_t( 17 ) );
  579. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  580. std::cout.put( '\n' );
  581.  
  582. list_2.insert( --list_2.cend(), 2, foo_t( 17 ) );
  583. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  584. std::cout.put( '\n' );
  585.  
  586. list_2.insert( --list_2.cend(), vec.cbegin(), vec.cend() );
  587. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  588. std::cout.put( '\n' );
  589.  
  590. list_2.insert( list_2.cbegin(), --vec.cend(), vec.cend() );
  591. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  592. std::cout.put( '\n' );
  593.  
  594. list_2.sort();
  595. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  596. std::cout.put( '\n' );
  597.  
  598. list< foo_t > list_3( vec.cbegin(), vec.cend() );
  599. std::copy( list_3.begin(), list_3.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  600. std::cout.put( '\n' );
  601. }
Success #stdin #stdout 0s 2992KB
stdin
Standard input is empty
stdout
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 
0 0 1 2 2 3 4 4 5 6 6 7 8 8 9 10 10 11 12 12 13 14 14 15 16 16 17 18 18 19 20 22 24 26 28 30 32 34 36 38 
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 
38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2 0 
38 36 34 4 2 0 
38 36 34 4 2 0 42 42 42 42 42 42 
38 36 34 4 2 0 42 
36 34 4 2 0 42 
36 34 4 2 0 
0 2 4 6 8 10 12 14 
0 2 4 6 8 10 12 14 
0 1 2 4 6 8 10 12 14 
0 1 2 4 6 8 10 12 13 14 
42 42 42 42 0 1 2 4 6 8 10 12 13 14 
42 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 42 
42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 42 
42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 17 17 42 
42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 17 17 0 2 4 6 8 10 12 14 42 
14 42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 17 17 0 2 4 6 8 10 12 14 42 
0 0 1 2 2 4 4 6 6 8 8 10 10 12 12 13 14 14 14 17 17 17 17 17 42 42 42 42 42 42 42 42 
0 2 4 6 8 10 12 14