1 // Copyright (C) 2011-2016 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 
19 #include <testsuite_hooks.h>
20 
21 namespace __gnu_test
22 {
23   template<typename _Tp>
24     struct CopyableValueType
25     {
26       typedef _Tp value_type;
27     };
28 
29   template<typename _Tp1, typename _Tp2>
30     struct CopyableValueType<std::pair<const _Tp1, _Tp2> >
31     {
32       typedef std::pair<_Tp1, _Tp2> value_type;
33     };
34 
35   template<typename _Tp>
36     struct generate_unique
37     {
38       typedef _Tp value_type;
39 
40       value_type build()
41       {
42 	static value_type _S_;
43 	++_S_;
44 	return _S_;
45       }
46     };
47 
48   template<typename _Tp1, typename _Tp2>
49     struct generate_unique<std::pair<_Tp1, _Tp2> >
50     {
51       typedef _Tp1 first_type;
52       typedef _Tp2 second_type;
53       typedef std::pair<_Tp1, _Tp2> pair_type;
54 
55       pair_type build()
56       {
57 	static first_type _S_1;
58 	static second_type _S_2;
59 	++_S_1;
60 	++_S_2;
61 	return pair_type(_S_1, _S_2);
62       }
63     };
64 
65   template<typename _Tp>
66     struct KeyExtractor
67     {
68       static _Tp get_key(const _Tp& val)
69       { return val; }
70     };
71 
72   template<typename _Tp1, typename _Tp2>
73     struct KeyExtractor<std::pair<const _Tp1, _Tp2>>
74     {
75       static _Tp1 get_key(const std::pair<const _Tp1, _Tp2>& val)
76       { return val.first; }
77     };
78 
79   template<typename _Tp>
80     void use_erased_local_iterator()
81     {
82       bool test __attribute__((unused)) = true;
83 
84       typedef _Tp cont_type;
85       typedef typename cont_type::value_type cont_val_type;
86       typedef typename CopyableValueType<cont_val_type>::value_type val_type;
87       generate_unique<val_type> gu;
88 
89       cont_type c;
90       for (size_t i = 0; i != 5; ++i)
91 	c.insert(gu.build());
92 
93       typename cont_type::local_iterator it, end;
94       for (size_t i = 0; i != c.bucket_count(); ++i)
95       {
96 	it = c.begin(i);
97 	end = c.end(i);
98 	if (it != end)
99 	  break;
100       }
101       typename cont_type::key_type key = KeyExtractor<cont_val_type>::get_key(*it);
102       c.erase(key);
103       VERIFY( it != end );
104   }
105 
106   template<typename _Tp>
107     void use_invalid_local_iterator()
108     {
109       bool test __attribute__((unused)) = true;
110 
111       typedef _Tp cont_type;
112       typedef typename cont_type::value_type cont_val_type;
113       typedef typename CopyableValueType<cont_val_type>::value_type val_type;
114       generate_unique<val_type> gu;
115 
116       cont_type c;
117       for (size_t i = 0; i != 5; ++i)
118 	c.insert(gu.build());
119 
120       typename cont_type::local_iterator it;
121       for (size_t i = 0; i != c.bucket_count(); ++i)
122       {
123 	it = c.begin(i);
124 	if (it != c.end(i))
125 	  break;
126       }
127       cont_val_type val = *it;
128       c.clear();
129       VERIFY( *it == val );
130     }
131 
132   template<typename _Tp>
133     void invalid_local_iterator_compare()
134     {
135       bool test __attribute__((unused)) = true;
136 
137       typedef _Tp cont_type;
138       typedef typename cont_type::value_type cont_val_type;
139       typedef typename CopyableValueType<cont_val_type>::value_type val_type;
140       generate_unique<val_type> gu;
141 
142       cont_type c;
143       for (size_t i = 0; i != 5; ++i)
144 	c.insert(gu.build());
145 
146       typename cont_type::local_iterator it1, it2;
147       size_t i;
148       for (i = 0; i != c.bucket_count(); ++i)
149       {
150 	it1 = c.begin(i);
151 	if (it1 != c.end(i))
152 	  break;
153       }
154       VERIFY( i != c.bucket_count() );
155       for (++i; i != c.bucket_count(); ++i)
156       {
157 	it2 = c.begin(i);
158 	if (it2 != c.end(i))
159 	  break;
160       }
161 
162       VERIFY( it1 != it2 );
163     }
164 
165   template<typename _Tp>
166     void invalid_local_iterator_range()
167     {
168       bool test __attribute__((unused)) = true;
169 
170       typedef _Tp cont_type;
171       typedef typename cont_type::value_type cont_val_type;
172       typedef typename CopyableValueType<cont_val_type>::value_type val_type;
173       generate_unique<val_type> gu;
174 
175       cont_type c;
176       for (size_t i = 0; i != 5; ++i)
177 	c.insert(gu.build());
178 
179       typename cont_type::local_iterator it, end;
180       for (size_t i = 0; i != c.bucket_count(); ++i)
181       {
182 	it = c.begin(i);
183 	end = c.end(i);
184 	if (it != end)
185 	  break;
186       }
187       c.insert(end, it);
188     }
189 }
190 
191