1// Copyright (C) 2009-2015 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// 25.3.1.2 [lib.stable.sort] 19 20#include <algorithm> 21#include <testsuite_hooks.h> 22#include <testsuite_iterators.h> 23 24using __gnu_test::test_container; 25using __gnu_test::random_access_iterator_wrapper; 26using __gnu_test::copy_tracker; 27using __gnu_test::copy_constructor; 28using __gnu_test::assignment_operator; 29using __gnu_test::destructor; 30 31typedef test_container<copy_tracker, random_access_iterator_wrapper> Container; 32 33const int A[] = {10, 20, 1, 11, 2, 21, 28, 29, 12, 35, 15, 27, 6, 16, 7, 34 25, 17, 8, 23, 18, 9, 19, 24, 30, 13, 4, 14, 22, 26, 0}; 35 36void 37test_mem1(int throw_count) 38{ 39 bool test __attribute__((unused)) = true; 40 41 copy_tracker vals[30]; 42 for(int i = 0; i < 30; ++i) 43 vals[i] = A[i]; 44 45 Container con(vals, vals + 30); 46 copy_tracker::reset(); 47 copy_constructor::throw_on(throw_count); 48 int throw_occurred = 0; 49 try 50 { 51 std::stable_sort(con.begin(), con.end()); 52 } 53 catch(...) 54 { 55 throw_occurred = 1; 56 } 57 58 // If a throw occurred in copy_constructor, we will end up with one more 59 // copy_construct than destructor. 60 VERIFY( destructor::count() == copy_constructor::count() - throw_occurred ); 61} 62 63bool 64is_ordered(const copy_tracker& lhs, const copy_tracker& rhs) 65{ return lhs < rhs; } 66 67void 68test_mem2(int throw_count) 69{ 70 bool test __attribute__((unused)) = true; 71 72 copy_tracker vals[30]; 73 for(int i = 0; i < 30; ++i) 74 vals[i] = A[i]; 75 76 Container con(vals, vals + 30); 77 copy_tracker::reset(); 78 copy_constructor::throw_on(throw_count); 79 int throw_occurred = 0; 80 try 81 { 82 std::stable_sort(con.begin(), con.end(), is_ordered); 83 } 84 catch(...) 85 { 86 throw_occurred = 1; 87 } 88 89 // If a throw occurred in copy_constructor, we will end up with one more 90 // copy_construct than destructor. 91 VERIFY( destructor::count() == copy_constructor::count() - throw_occurred ); 92} 93 94int main() 95{ 96 for(int i = 0; i < 60; ++i) 97 { 98 test_mem1(i); 99 test_mem2(i); 100 } 101 102 return 0; 103} 104