1// -*- C++ -*-
2
3// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the terms
7// of the GNU General Public License as published by the Free Software
8// Foundation; either version 3, or (at your option) any later
9// version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14// General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING3.  If not see
18// <http://www.gnu.org/licenses/>.
19
20#ifndef _GLIBCXX_TESTSUITE_CONTAINERS_H
21#define _GLIBCXX_TESTSUITE_CONTAINERS_H
22
23#include <cassert>
24#include <testsuite_container_traits.h>
25
26// Container requirement testing.
27namespace __gnu_test
28{
29  // Compile-time typedef testing.
30  template<typename _Tp, bool _Bt = traits<_Tp>::is_container::value>
31    struct basic_types
32    {
33      // Base container requirements (table 80)
34      typedef _Tp 					test_type;
35      typedef typename test_type::value_type 		value_type;
36      typedef typename test_type::pointer 		pointer;
37      typedef typename test_type::const_pointer 	const_pointer;
38      typedef typename test_type::reference 		reference;
39      typedef typename test_type::const_reference 	const_reference;
40      typedef typename test_type::iterator 		iterator;
41      typedef typename test_type::const_iterator 	const_iterator;
42      typedef typename test_type::size_type 		size_type;
43      typedef typename test_type::difference_type 	difference_type;
44    };
45
46  // Conditional typedef testing, positive.
47  template<typename _Tp, bool _Bt = traits<_Tp>::is_reversible::value>
48    struct reversible_types
49    {
50      // Reversible container requirements (table 81)
51      typedef _Tp 					 test_type;
52      typedef typename test_type::reverse_iterator 	 reverse_iterator;
53      typedef typename test_type::const_reverse_iterator const_reverse_iterator;
54    };
55
56  template<typename _Tp, bool _Bt = traits<_Tp>::is_allocator_aware::value>
57    struct allocator_aware_types
58    {
59      // Allocator-aware requirements (table 82)
60      typedef _Tp 					 test_type;
61      typedef typename test_type::allocator_type      	 allocator_type;
62    };
63
64  template<typename _Tp, bool _Bt = traits<_Tp>::is_associative::value>
65    struct associative_types
66    {
67      // Associative container requirements (table 85)
68      typedef _Tp 					 test_type;
69      typedef typename test_type::key_type		 key_type;
70      typedef typename test_type::key_compare		 key_compare;
71      typedef typename test_type::value_compare		 value_compare;
72    };
73
74  template<typename _Tp, bool = traits<_Tp>::is_unordered::value>
75    struct unordered_types
76    {
77      // Unordered associative container requirements (table 87)
78      typedef _Tp 					 test_type;
79      typedef typename test_type::key_type		 key_type;
80      typedef typename test_type::hasher		 hasher;
81      typedef typename test_type::key_equal		 key_equal;
82      typedef typename test_type::local_iterator	 local_iterator;
83      typedef typename test_type::const_local_iterator	 const_local_iterator;
84    };
85
86  template<typename _Tp, bool _Bt = traits<_Tp>::is_mapped::value>
87    struct mapped_types
88    {
89      typedef _Tp 					 test_type;
90      typedef typename test_type::mapped_type	   	 mapped_type;
91    };
92
93  template<typename _Tp, bool = traits<_Tp>::is_adaptor::value>
94    struct adaptor_types
95    {
96      // Container adaptor requirements.
97      typedef _Tp 					test_type;
98      typedef typename test_type::value_type 		value_type;
99      typedef typename test_type::reference 		reference;
100      typedef typename test_type::const_reference 	const_reference;
101      typedef typename test_type::size_type 		size_type;
102      typedef typename test_type::container_type 	container_type;
103    };
104
105  // Conditional typedef testing, negative.
106  template<typename _Tp>
107    struct basic_types<_Tp, false> { };
108
109  template<typename _Tp>
110    struct adaptor_types<_Tp, false> { };
111
112  template<typename _Tp>
113    struct reversible_types<_Tp, false> { };
114
115  template<typename _Tp>
116    struct allocator_aware_types<_Tp, false> { };
117
118  template<typename _Tp>
119    struct associative_types<_Tp, false> { };
120
121  template<typename _Tp>
122    struct unordered_types<_Tp, false> { };
123
124  template<typename _Tp>
125    struct mapped_types<_Tp, false> { };
126
127  // Primary template.
128  template<typename _Tp>
129    struct types
130    : basic_types<_Tp>, adaptor_types<_Tp>, reversible_types<_Tp>,
131      allocator_aware_types<_Tp>, associative_types<_Tp>,
132      unordered_types<_Tp>, mapped_types<_Tp>
133    { };
134
135
136  // Run-time test for constant_iterator requirements.
137  template<typename _Tp, bool = traits<_Tp>::is_allocator_aware::value>
138    struct populate
139    {
140      populate(_Tp& container)
141      {
142	// Avoid uninitialized warnings, requires DefaultContructible.
143	typedef typename _Tp::value_type value_type;
144	container.insert(container.begin(), value_type());
145	container.insert(container.begin(), value_type());
146      }
147  };
148
149  template<typename _Tp>
150    struct populate<_Tp, false>
151    {
152      populate(_Tp& container) { }
153    };
154
155  template<typename _Tp, bool = traits<_Tp>::is_reversible::value>
156    struct reverse_members
157    {
158      reverse_members(_Tp& container)
159      {
160	assert( container.crbegin() == container.rbegin() );
161	assert( container.crend() == container.rend() );
162	assert( container.crbegin() != container.crend() );
163      }
164    };
165
166  template<typename _Tp>
167    struct reverse_members<_Tp, false>
168    {
169      reverse_members(_Tp& container) { }
170    };
171
172  // DR 691.
173  template<typename _Tp, bool = traits<_Tp>::is_unordered::value>
174    struct forward_members_unordered
175    {
176      forward_members_unordered(typename _Tp::value_type& v)
177      {
178	typedef _Tp					test_type;
179	test_type container;
180	container.insert(v);
181	assert( container.cbegin(0) == container.begin(0) );
182	assert( container.cend(0) == container.end(0) );
183	const typename test_type::size_type bn = container.bucket(1);
184	assert( container.cbegin(bn) != container.cend(bn) );
185      }
186    };
187
188  template<typename _Tp>
189    struct forward_members_unordered<_Tp, false>
190    {
191      forward_members_unordered(_Tp& container) { }
192    };
193
194  template<typename _Tp>
195    struct citerator
196    {
197      typedef _Tp 					test_type;
198      typedef traits<test_type>				traits_type;
199      typedef typename test_type::value_type 		value_type;
200
201      static test_type _S_container;
202
203      // Unconditional.
204      struct forward_members
205      {
206	forward_members()
207	{
208	  assert( _S_container.cbegin() == _S_container.begin() );
209	  assert( _S_container.cend() == _S_container.end() );
210	  assert( _S_container.cbegin() != _S_container.cend() );
211	}
212      };
213
214      // Run test.
215      citerator()
216      {
217	populate<test_type> p(_S_container);
218	forward_members m1;
219	reverse_members<test_type> m2(_S_container);
220      }
221  };
222
223  template<typename _Tp>
224  _Tp citerator<_Tp>::_S_container;
225
226
227} // namespace __gnu_test
228
229#endif
230