1  // Copyright (C) 2001-2023 Free Software Foundation, Inc.
       2  //
       3  // This file is part of the GNU ISO C++ Library.  This library is free
       4  // software; you can redistribute it and/or modify it under the
       5  // terms of the GNU General Public License as published by the
       6  // Free Software Foundation; either version 3, or (at your option)
       7  // any later version.
       8  
       9  // This library is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  
      14  // You should have received a copy of the GNU General Public License along
      15  // with this library; see the file COPYING3.  If not see
      16  // <http://www.gnu.org/licenses/>.
      17  
      18  // 23.2.2.3 list modifiers [lib.list.modifiers]
      19  
      20  #include <testsuite_hooks.h>
      21  
      22  // range and fill insert/erase + clear
      23  // missing: o  fill insert disguised as a range insert in all its variants
      24  //          o  exception effects
      25  template<typename _Tp>
      26  void
      27  modifiers1()
      28  {
      29    typedef _Tp list_type;
      30    typedef typename list_type::iterator iterator;
      31    typedef typename list_type::value_type value_type;
      32    
      33    using __gnu_test::copy_constructor;
      34    using __gnu_test::destructor;
      35  
      36    list_type list0301;
      37    value_type::reset();
      38  
      39    // fill insert at beginning of list / empty list
      40    list0301.insert(list0301.begin(), 3, value_type(11)); // should be [11 11 11]
      41    VERIFY(list0301.size() == 3);
      42    VERIFY(copy_constructor::count() == 3);
      43  
      44    // save iterators to verify post-insert validity
      45    iterator b = list0301.begin();
      46    iterator m = list0301.end(); --m;
      47    iterator e = list0301.end();
      48  
      49    // fill insert at end of list
      50    value_type::reset();
      51    list0301.insert(list0301.end(), 3, value_type(13)); // should be [11 11 11 13 13 13]
      52    VERIFY(list0301.size() == 6);
      53    VERIFY(copy_constructor::count() == 3);
      54    VERIFY(b == list0301.begin() && b->id() == 11);
      55    VERIFY(e == list0301.end());
      56    VERIFY(m->id() == 11);
      57  
      58    // fill insert in the middle of list
      59    ++m;
      60    value_type::reset();
      61    list0301.insert(m, 3, value_type(12)); // should be [11 11 11 12 12 12 13 13 13]
      62    VERIFY(list0301.size() == 9);
      63    VERIFY(copy_constructor::count() == 3);
      64    VERIFY(b == list0301.begin() && b->id() == 11);
      65    VERIFY(e == list0301.end());
      66    VERIFY(m->id() == 13);
      67  
      68    // single erase
      69    value_type::reset();
      70    m = list0301.erase(m); // should be [11 11 11 12 12 12 13 13]
      71    VERIFY(list0301.size() == 8);
      72    VERIFY(destructor::count() == 1);
      73    VERIFY(b == list0301.begin() && b->id() == 11);
      74    VERIFY(e == list0301.end());
      75    VERIFY(m->id() == 13);
      76  
      77    // range erase
      78    value_type::reset();
      79    m = list0301.erase(list0301.begin(), m); // should be [13 13]
      80    VERIFY(list0301.size() == 2);
      81    VERIFY(destructor::count() == 6);
      82    VERIFY(m->id() == 13);
      83  
      84    // range fill at beginning
      85    const int A[] = {321, 322, 333};
      86    const int N = sizeof(A) / sizeof(int);
      87    value_type::reset();
      88    b = list0301.begin();
      89    list0301.insert(b, A, A + N); // should be [321 322 333 13 13]
      90    VERIFY(list0301.size() == 5);
      91  #if __cplusplus >= 201103L
      92    VERIFY(copy_constructor::count() == 0);
      93  #else
      94    VERIFY(copy_constructor::count() == 3);
      95  #endif
      96    VERIFY(m->id() == 13);
      97  
      98    // range fill at end
      99    value_type::reset();
     100    list0301.insert(e, A, A + N); // should be [321 322 333 13 13 321 322 333]
     101    VERIFY(list0301.size() == 8);
     102  #if __cplusplus >= 201103L
     103    VERIFY(copy_constructor::count() == 0);
     104  #else
     105    VERIFY(copy_constructor::count() == 3);
     106  #endif
     107    VERIFY(e == list0301.end());
     108    VERIFY(m->id() == 13);
     109  
     110    // range fill in middle
     111    value_type::reset();
     112    list0301.insert(m, A, A + N);
     113    VERIFY(list0301.size() == 11);
     114  #if __cplusplus >= 201103L
     115    VERIFY(copy_constructor::count() == 0);
     116  #else
     117    VERIFY(copy_constructor::count() == 3);
     118  #endif
     119    VERIFY(e == list0301.end());
     120    VERIFY(m->id() == 13);
     121  
     122    value_type::reset();
     123    list0301.clear();
     124    VERIFY(list0301.size() == 0);
     125    VERIFY(destructor::count() == 11);
     126    VERIFY(e == list0301.end());
     127  }