]>
Commit | Line | Data |
---|---|---|
a5544970 | 1 | // Copyright (C) 2018-2019 Free Software Foundation, Inc. |
af55b3af JW |
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 | // { dg-do run } | |
19 | ||
20 | #include <vector> | |
21 | #include <stdexcept> | |
22 | #include <limits> | |
23 | #include <testsuite_hooks.h> | |
24 | ||
f73a5316 | 25 | typedef std::vector<char> test_type; |
af55b3af JW |
26 | |
27 | typedef test_type::size_type size_type; | |
28 | typedef test_type::difference_type difference_type; | |
29 | ||
30 | const difference_type diffmax = std::numeric_limits<difference_type>::max(); | |
31 | ||
32 | void | |
33 | test01() | |
34 | { | |
35 | test_type v; | |
36 | VERIFY( v.max_size() <= diffmax ); | |
37 | } | |
38 | ||
39 | void | |
40 | test02() | |
41 | { | |
42 | size_type n = size_type(diffmax) + 1; | |
43 | VERIFY( n > test_type().max_size() ); | |
44 | ||
45 | try { | |
46 | test_type v(n); | |
47 | VERIFY( false ); | |
48 | } catch (const std::length_error&) { } | |
49 | ||
50 | try { | |
51 | test_type v(n, 'x'); | |
52 | VERIFY( false ); | |
53 | } catch (const std::length_error&) { } | |
54 | ||
55 | try { | |
56 | test_type v(n, 'x', test_type::allocator_type()); | |
57 | VERIFY( false ); | |
58 | } catch (const std::length_error&) { } | |
59 | } | |
60 | ||
61 | #ifdef __GLIBCXX_TYPE_INT_N_0 | |
62 | template<typename T, typename U, bool = (sizeof(T) > sizeof(long long))> | |
63 | struct Base_ | |
64 | { | |
65 | typedef T difference_type; | |
66 | typedef U size_type; | |
67 | }; | |
68 | ||
69 | template<typename T, typename U> | |
70 | struct Base_<T, U, false> | |
71 | { | |
72 | typedef long long difference_type; | |
73 | typedef unsigned long long size_type; | |
74 | }; | |
75 | ||
76 | typedef Base_<__GLIBCXX_TYPE_INT_N_0, unsigned __GLIBCXX_TYPE_INT_N_0> Base; | |
77 | #else | |
78 | struct Base | |
79 | { | |
80 | typedef long long difference_type; | |
81 | typedef unsigned long long size_type; | |
82 | }; | |
83 | #endif | |
84 | ||
85 | // An iterator with a difference_type larger than ptrdiff_t | |
86 | struct Iter : Base | |
87 | { | |
88 | typedef std::random_access_iterator_tag iterator_category; | |
89 | typedef char value_type; | |
90 | typedef const char* pointer; | |
91 | typedef const char& reference; | |
92 | using Base::difference_type; | |
93 | ||
94 | Iter() : n(0) { } | |
95 | Iter(size_type n) : n(n) { } | |
96 | ||
97 | reference operator*() const { return value; } | |
98 | pointer operator->() const { return &value; } | |
99 | ||
100 | Iter& operator++() { ++n; return *this; } | |
101 | Iter operator++(int) { Iter tmp(*this); ++n; return tmp; } | |
102 | Iter& operator--() { --n; return *this; } | |
103 | Iter operator--(int) { Iter tmp(*this); --n; return tmp; } | |
104 | ||
105 | Iter& operator+=(difference_type d) { n += d; return *this; } | |
106 | Iter& operator-=(difference_type d) { n -= d; return *this; } | |
107 | ||
108 | difference_type operator-(const Iter& rhs) const { return n - rhs.n; } | |
109 | ||
110 | reference operator[](difference_type d) const { return value; } | |
111 | ||
112 | bool operator==(const Iter& rhs) const { return n == rhs.n; } | |
113 | bool operator!=(const Iter& rhs) const { return n != rhs.n; } | |
114 | bool operator<(const Iter& rhs) const { return n < rhs.n; } | |
115 | bool operator>(const Iter& rhs) const { return n > rhs.n; } | |
116 | bool operator<=(const Iter& rhs) const { return n <= rhs.n; } | |
117 | bool operator>=(const Iter& rhs) const { return n >= rhs.n; } | |
118 | ||
119 | private: | |
120 | size_type n; | |
121 | static const char value = 'x'; | |
122 | }; | |
123 | ||
b57d432b JW |
124 | const char Iter::value; |
125 | ||
af55b3af JW |
126 | Iter operator+(Iter i, Iter::difference_type n) { return i += n; } |
127 | Iter operator+(Iter::difference_type n, Iter i) { return i += n; } | |
128 | Iter operator-(Iter::difference_type n, Iter i) { return i -= n; } | |
129 | ||
130 | void | |
131 | test03() | |
132 | { | |
133 | Iter first, last(Iter::size_type(diffmax) + 1); | |
134 | VERIFY( std::distance(first, last) > test_type().max_size() ); | |
135 | ||
136 | try { | |
137 | test_type vec(first, last); | |
138 | VERIFY(false); | |
139 | } catch (const std::length_error&) { } | |
140 | } | |
141 | ||
142 | int | |
143 | main() | |
144 | { | |
145 | test01(); | |
146 | test02(); | |
147 | test03(); | |
148 | } |