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