1// Copyright (C) 2007, 2009, 2010 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 Pred 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.5 class vector<bool> [lib.vector.bool]
19
20// { dg-do run { xfail *-*-darwin8.[0-4].* } }
21
22#include <vector>
23#include <stdexcept>
24#include <testsuite_hooks.h>
25
26#ifdef _GLIBCXX_DEBUG
27  using std::_GLIBCXX_STD_D::_S_word_bit;
28#elif defined(_GLIBCXX_PROFILE)
29  using std::_GLIBCXX_STD_PR::_S_word_bit;
30#else
31  using std::_S_word_bit;
32#endif
33
34inline void
35check_cap_ge_size(const std::vector<bool>& x)
36{
37  if (x.capacity() < x.size())
38    throw std::logic_error("");
39}
40
41inline void
42check_cap_eq_maxsize(const std::vector<bool>& x)
43{
44  if (x.capacity() != x.max_size())
45    throw std::logic_error("");
46}
47
48// libstdc++/31370
49void test01()
50{
51  bool test __attribute__((unused)) = true;
52  int myexit = 0;
53
54  try
55    {
56      std::vector<bool> x;
57      x.reserve(x.max_size());
58      check_cap_eq_maxsize(x);
59    }
60  catch(std::bad_alloc&)
61    { }
62  catch(std::exception&)
63    { ++myexit; }
64
65  // When doubling is too big, but smaller is sufficient, the resize
66  // should do smaller and be happy.  It certainly shouldn't throw
67  // other exceptions or crash.
68  try
69    {
70      std::vector<bool> x;
71      x.resize(x.max_size() / 2 + 1, false);
72      for(int i = 0; i < _S_word_bit; ++i)
73	x.push_back(false);
74      check_cap_ge_size(x);
75    }
76  catch(std::bad_alloc&)
77    { }
78  catch(std::exception&)
79    { ++myexit; }
80
81  try
82    {
83      std::vector<bool> x;
84      x.resize(x.max_size() / 2 + 1, false);
85      x.insert(x.end(), _S_word_bit, false);
86      check_cap_ge_size(x);
87    }
88  catch(std::bad_alloc&)
89    { }
90  catch(std::exception&)
91    { ++myexit; }
92
93  try
94    {
95      std::vector<bool> x;
96      x.resize(x.max_size() / 2 + 1, false);
97      std::vector<bool> y(_S_word_bit, false);
98      x.insert(x.end(), y.begin(), y.end());
99      check_cap_ge_size(x);
100    }
101  catch(std::bad_alloc&)
102    { }
103  catch(std::exception&)
104    { ++myexit; }
105
106  // These tests are currently only relevant to bool: don't get burned
107  // by the attempt to round up when near the max size.
108  try
109    {
110      std::vector<bool> x;
111      x.resize(x.max_size() - _S_word_bit, false);
112      for(int i = 0; i < _S_word_bit; ++i)
113	x.push_back(false);
114      check_cap_ge_size(x);
115    }
116  catch(std::bad_alloc&)
117    { }
118  catch(std::exception&)
119    { ++myexit; }
120
121  try
122    {
123      std::vector<bool> x;
124      x.resize(x.max_size() - _S_word_bit, false);
125      x.insert(x.end(), _S_word_bit, false);
126      check_cap_ge_size(x);
127    }
128  catch(std::bad_alloc&)
129    { }
130  catch(std::exception&)
131    { ++myexit; }
132
133  try
134    {
135      std::vector<bool> x;
136      x.resize(x.max_size() - _S_word_bit, false);
137      std::vector<bool> y(_S_word_bit, false);
138      x.insert(x.end(), y.begin(), y.end());
139      check_cap_ge_size(x);
140    }
141  catch(std::bad_alloc&)
142    { }
143  catch(std::exception&)
144    { ++myexit; }
145
146  // Attempts to put in more than max_size() items should result in a
147  // length error.
148  try
149    {
150      std::vector<bool> x;
151      x.resize(x.max_size() - _S_word_bit, false);
152      for(int i = 0; i < _S_word_bit + 1; ++i)
153	x.push_back(false);
154      ++myexit;
155    }
156  catch(std::bad_alloc)
157    { }
158  catch(std::length_error)
159    { }
160  catch(std::exception)
161    { ++myexit; }
162
163  try
164    {
165      std::vector<bool> x;
166      x.resize(x.max_size() - _S_word_bit, false);
167      x.insert(x.end(), _S_word_bit + 1, false);
168      ++myexit;
169    }
170  catch(std::bad_alloc)
171    { }
172  catch(std::length_error)
173    { }
174  catch(std::exception)
175    { ++myexit; }
176
177  try
178    {
179      std::vector<bool> x;
180      x.resize(x.max_size() - _S_word_bit, false);
181      std::vector<bool> y(_S_word_bit + 1, false);
182      x.insert(x.end(), y.begin(), y.end());
183      ++myexit;
184    }
185  catch(std::bad_alloc)
186    { }
187  catch(std::length_error)
188    { }
189  catch(std::exception)
190    { ++myexit; }
191
192  VERIFY( !myexit );
193}
194
195int main()
196{
197  test01();
198  return 0;
199}
200