1// Copyright (C) 2011-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
19#include <testsuite_hooks.h>
20
21namespace __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