sl@0
|
1 |
/***********************************************************************************
|
sl@0
|
2 |
test_insert.h
|
sl@0
|
3 |
|
sl@0
|
4 |
* Copyright (c) 1997
|
sl@0
|
5 |
* Mark of the Unicorn, Inc.
|
sl@0
|
6 |
*
|
sl@0
|
7 |
* Permission to use, copy, modify, distribute and sell this software
|
sl@0
|
8 |
* and its documentation for any purpose is hereby granted without fee,
|
sl@0
|
9 |
* provided that the above copyright notice appear in all copies and
|
sl@0
|
10 |
* that both that copyright notice and this permission notice appear
|
sl@0
|
11 |
* in supporting documentation. Mark of the Unicorn makes no
|
sl@0
|
12 |
* representations about the suitability of this software for any
|
sl@0
|
13 |
* purpose. It is provided "as is" without express or implied warranty.
|
sl@0
|
14 |
|
sl@0
|
15 |
***********************************************************************************/
|
sl@0
|
16 |
#ifndef test_insert_H_
|
sl@0
|
17 |
#define test_insert_H_
|
sl@0
|
18 |
|
sl@0
|
19 |
# include "Prefix.h"
|
sl@0
|
20 |
# if defined (EH_NEW_HEADERS)
|
sl@0
|
21 |
# include <utility>
|
sl@0
|
22 |
# include <vector>
|
sl@0
|
23 |
# include <cassert>
|
sl@0
|
24 |
# include <climits>
|
sl@0
|
25 |
# else
|
sl@0
|
26 |
# include <vector.h>
|
sl@0
|
27 |
# include <assert.h>
|
sl@0
|
28 |
# include <limits.h>
|
sl@0
|
29 |
# endif
|
sl@0
|
30 |
#include "random_number.h"
|
sl@0
|
31 |
#include "nc_alloc.h"
|
sl@0
|
32 |
#include "ThrowCompare.h"
|
sl@0
|
33 |
|
sl@0
|
34 |
// A classification system for containers, for verification
|
sl@0
|
35 |
struct container_tag {};
|
sl@0
|
36 |
struct sequence_container_tag {};
|
sl@0
|
37 |
struct associative_container_tag {};
|
sl@0
|
38 |
|
sl@0
|
39 |
struct set_tag {};
|
sl@0
|
40 |
struct multiset_tag {};
|
sl@0
|
41 |
struct map_tag {};
|
sl@0
|
42 |
struct multimap_tag {};
|
sl@0
|
43 |
|
sl@0
|
44 |
template <class C, class Iter>
|
sl@0
|
45 |
size_t CountNewItems( const C&, const Iter& firstNew,
|
sl@0
|
46 |
const Iter& lastNew, sequence_container_tag )
|
sl@0
|
47 |
{
|
sl@0
|
48 |
size_t dist = 0;
|
sl@0
|
49 |
#if 0 //def __SUNPRO_CC
|
sl@0
|
50 |
EH_DISTANCE( firstNew, lastNew, dist );
|
sl@0
|
51 |
#else
|
sl@0
|
52 |
EH_DISTANCE( Iter(firstNew), Iter(lastNew), dist );
|
sl@0
|
53 |
#endif
|
sl@0
|
54 |
return dist;
|
sl@0
|
55 |
}
|
sl@0
|
56 |
|
sl@0
|
57 |
template <class C, class Iter>
|
sl@0
|
58 |
size_t CountNewItems( const C& c, const Iter& firstNew,
|
sl@0
|
59 |
const Iter& lastNew, multimap_tag )
|
sl@0
|
60 |
{
|
sl@0
|
61 |
return CountNewItems( c, firstNew, lastNew, sequence_container_tag() );
|
sl@0
|
62 |
}
|
sl@0
|
63 |
|
sl@0
|
64 |
template <class C, class Iter>
|
sl@0
|
65 |
size_t CountNewItems( const C& c, const Iter& firstNew,
|
sl@0
|
66 |
const Iter& lastNew, multiset_tag )
|
sl@0
|
67 |
{
|
sl@0
|
68 |
return CountNewItems( c, firstNew, lastNew, sequence_container_tag() );
|
sl@0
|
69 |
}
|
sl@0
|
70 |
|
sl@0
|
71 |
|
sl@0
|
72 |
template <class C, class Iter, class KeyOfValue>
|
sl@0
|
73 |
#ifdef __BORLANDC__
|
sl@0
|
74 |
size_t CountUniqueItems_Aux( const C& original, const Iter& firstNew,
|
sl@0
|
75 |
#else
|
sl@0
|
76 |
size_t CountUniqueItems_Aux( const C& original, Iter firstNew,
|
sl@0
|
77 |
#endif
|
sl@0
|
78 |
Iter lastNew, const KeyOfValue& keyOfValue )
|
sl@0
|
79 |
{
|
sl@0
|
80 |
typedef typename C::key_type key;
|
sl@0
|
81 |
typedef typename C::const_iterator const_iter;
|
sl@0
|
82 |
typedef EH_STD::vector<key> key_list;
|
sl@0
|
83 |
typedef typename key_list::iterator key_iterator;
|
sl@0
|
84 |
key_list keys;
|
sl@0
|
85 |
size_t dist = 0;
|
sl@0
|
86 |
#ifdef __SUNPRO_CC
|
sl@0
|
87 |
EH_DISTANCE( firstNew, lastNew, dist );
|
sl@0
|
88 |
#else
|
sl@0
|
89 |
EH_DISTANCE( Iter(firstNew), Iter(lastNew), dist );
|
sl@0
|
90 |
#endif
|
sl@0
|
91 |
keys.reserve( dist );
|
sl@0
|
92 |
for ( Iter x = firstNew; x != lastNew; ++x )
|
sl@0
|
93 |
keys.push_back( keyOfValue(*x) );
|
sl@0
|
94 |
|
sl@0
|
95 |
EH_STD::sort( keys.begin(), keys.end() );
|
sl@0
|
96 |
key_iterator last = EH_STD::unique( keys.begin(), keys.end() );
|
sl@0
|
97 |
|
sl@0
|
98 |
size_t cnt = 0;
|
sl@0
|
99 |
for ( key_iterator tmp = keys.begin(); tmp != last; ++tmp )
|
sl@0
|
100 |
{
|
sl@0
|
101 |
if ( const_iter(original.find( *tmp )) == const_iter(original.end()) )
|
sl@0
|
102 |
++cnt;
|
sl@0
|
103 |
}
|
sl@0
|
104 |
return cnt;
|
sl@0
|
105 |
}
|
sl@0
|
106 |
|
sl@0
|
107 |
#if ! defined (__SGI_STL)
|
sl@0
|
108 |
EH_BEGIN_NAMESPACE
|
sl@0
|
109 |
template <class T>
|
sl@0
|
110 |
struct identity
|
sl@0
|
111 |
{
|
sl@0
|
112 |
const T& operator()( const T& x ) const { return x; }
|
sl@0
|
113 |
};
|
sl@0
|
114 |
# if ! defined (__KCC)
|
sl@0
|
115 |
template <class _Pair>
|
sl@0
|
116 |
struct select1st : public unary_function<_Pair, typename _Pair::first_type> {
|
sl@0
|
117 |
const typename _Pair::first_type& operator()(const _Pair& __x) const {
|
sl@0
|
118 |
return __x.first;
|
sl@0
|
119 |
}
|
sl@0
|
120 |
};
|
sl@0
|
121 |
# endif
|
sl@0
|
122 |
EH_END_NAMESPACE
|
sl@0
|
123 |
#endif
|
sl@0
|
124 |
|
sl@0
|
125 |
template <class C, class Iter>
|
sl@0
|
126 |
size_t CountUniqueItems( const C& original, const Iter& firstNew,
|
sl@0
|
127 |
const Iter& lastNew, set_tag )
|
sl@0
|
128 |
{
|
sl@0
|
129 |
typedef typename C::value_type value_type;
|
sl@0
|
130 |
return CountUniqueItems_Aux( original, firstNew, lastNew,
|
sl@0
|
131 |
EH_STD::identity<value_type>() );
|
sl@0
|
132 |
}
|
sl@0
|
133 |
|
sl@0
|
134 |
template <class C, class Iter>
|
sl@0
|
135 |
size_t CountUniqueItems( const C& original, const Iter& firstNew,
|
sl@0
|
136 |
const Iter& lastNew, map_tag )
|
sl@0
|
137 |
{
|
sl@0
|
138 |
#ifdef EH_MULTI_CONST_TEMPLATE_ARG_BUG
|
sl@0
|
139 |
return CountUniqueItems_Aux( original, firstNew, lastNew,
|
sl@0
|
140 |
EH_SELECT1ST_HINT<C::value_type, C::key_type>() );
|
sl@0
|
141 |
#else
|
sl@0
|
142 |
typedef typename C::value_type value_type;
|
sl@0
|
143 |
return CountUniqueItems_Aux( original, firstNew, lastNew,
|
sl@0
|
144 |
EH_STD::select1st<value_type>() );
|
sl@0
|
145 |
#endif
|
sl@0
|
146 |
}
|
sl@0
|
147 |
|
sl@0
|
148 |
template <class C, class Iter>
|
sl@0
|
149 |
size_t CountNewItems( const C& original, const Iter& firstNew,
|
sl@0
|
150 |
const Iter& lastNew, map_tag )
|
sl@0
|
151 |
{
|
sl@0
|
152 |
return CountUniqueItems( original, firstNew, lastNew,
|
sl@0
|
153 |
container_category( original ) );
|
sl@0
|
154 |
}
|
sl@0
|
155 |
|
sl@0
|
156 |
template <class C, class Iter>
|
sl@0
|
157 |
size_t CountNewItems( const C& original, const Iter& firstNew,
|
sl@0
|
158 |
const Iter& lastNew, set_tag )
|
sl@0
|
159 |
{
|
sl@0
|
160 |
return CountUniqueItems( original, firstNew, lastNew,
|
sl@0
|
161 |
container_category( original ) );
|
sl@0
|
162 |
}
|
sl@0
|
163 |
|
sl@0
|
164 |
template <class C, class SrcIter>
|
sl@0
|
165 |
inline void VerifyInsertion( const C& original, const C& result,
|
sl@0
|
166 |
const SrcIter& firstNew, const SrcIter& lastNew,
|
sl@0
|
167 |
size_t, associative_container_tag )
|
sl@0
|
168 |
{
|
sl@0
|
169 |
typedef typename C::const_iterator DstIter;
|
sl@0
|
170 |
DstIter first1 = original.begin();
|
sl@0
|
171 |
DstIter first2 = result.begin();
|
sl@0
|
172 |
|
sl@0
|
173 |
DstIter* from_orig = new DstIter[original.size()];
|
sl@0
|
174 |
DstIter* last_from_orig = from_orig;
|
sl@0
|
175 |
|
sl@0
|
176 |
// fbp : for hashed containers, the following is needed :
|
sl@0
|
177 |
while ( first2 != result.end() )
|
sl@0
|
178 |
{
|
sl@0
|
179 |
EH_STD::pair<DstIter, DstIter> p = EH_STD::mismatch( first1, original.end(), first2 );
|
sl@0
|
180 |
if ( p.second != result.end() )
|
sl@0
|
181 |
{
|
sl@0
|
182 |
SrcIter srcItem = EH_STD::find( SrcIter(firstNew), SrcIter(lastNew), *p.second );
|
sl@0
|
183 |
|
sl@0
|
184 |
if (srcItem == lastNew)
|
sl@0
|
185 |
{
|
sl@0
|
186 |
// not found in input range, probably re-ordered from the orig
|
sl@0
|
187 |
DstIter* tmp;
|
sl@0
|
188 |
tmp = EH_STD::find( from_orig, last_from_orig, p.first );
|
sl@0
|
189 |
|
sl@0
|
190 |
// if already here, exclude
|
sl@0
|
191 |
if (tmp != last_from_orig)
|
sl@0
|
192 |
{
|
sl@0
|
193 |
EH_STD::copy(tmp+1, last_from_orig, tmp);
|
sl@0
|
194 |
last_from_orig--;
|
sl@0
|
195 |
}
|
sl@0
|
196 |
else
|
sl@0
|
197 |
{
|
sl@0
|
198 |
// register re-ordered element
|
sl@0
|
199 |
DstIter dstItem;
|
sl@0
|
200 |
dstItem = EH_STD::find( first1, original.end(), *p.first );
|
sl@0
|
201 |
EH_ASSERT( dstItem != original.end() );
|
sl@0
|
202 |
*last_from_orig = dstItem;
|
sl@0
|
203 |
last_from_orig++;
|
sl@0
|
204 |
++p.first;
|
sl@0
|
205 |
}
|
sl@0
|
206 |
}
|
sl@0
|
207 |
++p.second;
|
sl@0
|
208 |
}
|
sl@0
|
209 |
first1 = p.first;
|
sl@0
|
210 |
first2 = p.second;
|
sl@0
|
211 |
}
|
sl@0
|
212 |
|
sl@0
|
213 |
delete [] from_orig;
|
sl@0
|
214 |
}
|
sl@0
|
215 |
|
sl@0
|
216 |
// VC++
|
sl@0
|
217 |
template <class C, class SrcIter>
|
sl@0
|
218 |
inline void VerifyInsertion(
|
sl@0
|
219 |
const C& original, const C& result, const SrcIter& firstNew,
|
sl@0
|
220 |
const SrcIter& lastNew, size_t, set_tag )
|
sl@0
|
221 |
{
|
sl@0
|
222 |
VerifyInsertion( original, result, firstNew, lastNew,
|
sl@0
|
223 |
size_t(0), associative_container_tag() );
|
sl@0
|
224 |
}
|
sl@0
|
225 |
|
sl@0
|
226 |
template <class C, class SrcIter>
|
sl@0
|
227 |
inline void VerifyInsertion(const C& original, const C& result,
|
sl@0
|
228 |
const SrcIter& firstNew, const SrcIter& lastNew,
|
sl@0
|
229 |
size_t, multiset_tag )
|
sl@0
|
230 |
{
|
sl@0
|
231 |
VerifyInsertion( original, result, firstNew, lastNew,
|
sl@0
|
232 |
size_t(0), associative_container_tag() );
|
sl@0
|
233 |
}
|
sl@0
|
234 |
|
sl@0
|
235 |
template <class C, class SrcIter>
|
sl@0
|
236 |
inline void VerifyInsertion(
|
sl@0
|
237 |
const C& original, const C& result, const SrcIter& firstNew,
|
sl@0
|
238 |
const SrcIter& lastNew, size_t, map_tag )
|
sl@0
|
239 |
{
|
sl@0
|
240 |
VerifyInsertion( original, result, firstNew, lastNew,
|
sl@0
|
241 |
size_t(0), associative_container_tag() );
|
sl@0
|
242 |
}
|
sl@0
|
243 |
|
sl@0
|
244 |
template <class C, class SrcIter>
|
sl@0
|
245 |
inline void VerifyInsertion(
|
sl@0
|
246 |
const C& original, const C& result, const SrcIter& firstNew,
|
sl@0
|
247 |
const SrcIter& lastNew, size_t, multimap_tag )
|
sl@0
|
248 |
{
|
sl@0
|
249 |
VerifyInsertion( original, result, firstNew, lastNew,
|
sl@0
|
250 |
size_t(0), associative_container_tag() );
|
sl@0
|
251 |
}
|
sl@0
|
252 |
|
sl@0
|
253 |
template <class C, class SrcIter>
|
sl@0
|
254 |
void VerifyInsertion(
|
sl@0
|
255 |
# ifdef _MSC_VER
|
sl@0
|
256 |
const C& original, const C& result, SrcIter firstNew,
|
sl@0
|
257 |
SrcIter lastNew, size_t insPos, sequence_container_tag )
|
sl@0
|
258 |
# else
|
sl@0
|
259 |
const C& original, const C& result, const SrcIter& firstNew,
|
sl@0
|
260 |
const SrcIter& lastNew, size_t insPos, sequence_container_tag )
|
sl@0
|
261 |
# endif
|
sl@0
|
262 |
{
|
sl@0
|
263 |
typename C::const_iterator p1 = original.begin();
|
sl@0
|
264 |
typename C::const_iterator p2 = result.begin();
|
sl@0
|
265 |
SrcIter tmp(firstNew);
|
sl@0
|
266 |
|
sl@0
|
267 |
for ( size_t n = 0; n < insPos; n++, ++p1, ++p2)
|
sl@0
|
268 |
EH_ASSERT( *p1 == *p2 );
|
sl@0
|
269 |
|
sl@0
|
270 |
for (; tmp != lastNew; ++p2, ++tmp ) {
|
sl@0
|
271 |
EH_ASSERT(p2 != result.end());
|
sl@0
|
272 |
EH_ASSERT(*p2 == *tmp);
|
sl@0
|
273 |
}
|
sl@0
|
274 |
|
sl@0
|
275 |
for (; p2 != result.end(); ++p1, ++p2 )
|
sl@0
|
276 |
EH_ASSERT( *p1 == *p2 );
|
sl@0
|
277 |
EH_ASSERT( p1 == original.end() );
|
sl@0
|
278 |
}
|
sl@0
|
279 |
|
sl@0
|
280 |
template <class C, class SrcIter>
|
sl@0
|
281 |
inline void VerifyInsertion( const C& original, const C& result,
|
sl@0
|
282 |
const SrcIter& firstNew,
|
sl@0
|
283 |
const SrcIter& lastNew, size_t insPos )
|
sl@0
|
284 |
{
|
sl@0
|
285 |
EH_ASSERT( result.size() == original.size() +
|
sl@0
|
286 |
CountNewItems( original, firstNew, lastNew,
|
sl@0
|
287 |
container_category(original) ) );
|
sl@0
|
288 |
VerifyInsertion( original, result, firstNew, lastNew, insPos,
|
sl@0
|
289 |
container_category(original) );
|
sl@0
|
290 |
}
|
sl@0
|
291 |
|
sl@0
|
292 |
template <class C, class Value>
|
sl@0
|
293 |
void VerifyInsertN( const C& original, const C& result, size_t insCnt,
|
sl@0
|
294 |
const Value& val, size_t insPos )
|
sl@0
|
295 |
{
|
sl@0
|
296 |
typename C::const_iterator p1 = original.begin();
|
sl@0
|
297 |
typename C::const_iterator p2 = result.begin();
|
sl@0
|
298 |
(void)val; //*TY 02/06/2000 - to suppress unused variable warning under nondebug build
|
sl@0
|
299 |
|
sl@0
|
300 |
for ( size_t n = 0; n < insPos; n++ )
|
sl@0
|
301 |
EH_ASSERT( *p1++ == *p2++ );
|
sl@0
|
302 |
|
sl@0
|
303 |
while ( insCnt-- > 0 )
|
sl@0
|
304 |
{
|
sl@0
|
305 |
EH_ASSERT(p2 != result.end());
|
sl@0
|
306 |
EH_ASSERT(*p2 == val );
|
sl@0
|
307 |
++p2;
|
sl@0
|
308 |
}
|
sl@0
|
309 |
|
sl@0
|
310 |
while ( p2 != result.end() ) {
|
sl@0
|
311 |
EH_ASSERT( *p1 == *p2 );
|
sl@0
|
312 |
++p1; ++p2;
|
sl@0
|
313 |
}
|
sl@0
|
314 |
EH_ASSERT( p1 == original.end() );
|
sl@0
|
315 |
}
|
sl@0
|
316 |
|
sl@0
|
317 |
template <class C>
|
sl@0
|
318 |
void prepare_insert_n( C&, size_t ) {}
|
sl@0
|
319 |
|
sl@0
|
320 |
// Metrowerks 1.8 compiler requires that specializations appear first (!!)
|
sl@0
|
321 |
// or it won't call them. Fixed in 1.9, though.
|
sl@0
|
322 |
inline void MakeRandomValue(bool& b) { b = bool(random_number(2) != 0); }
|
sl@0
|
323 |
|
sl@0
|
324 |
template<class T>
|
sl@0
|
325 |
inline void MakeRandomValue(T&) {}
|
sl@0
|
326 |
|
sl@0
|
327 |
template <class C>
|
sl@0
|
328 |
struct test_insert_one
|
sl@0
|
329 |
{
|
sl@0
|
330 |
test_insert_one( const C& orig, int pos =-1 )
|
sl@0
|
331 |
: original( orig ), fPos( random_number( orig.size() ))
|
sl@0
|
332 |
{
|
sl@0
|
333 |
MakeRandomValue( fInsVal );
|
sl@0
|
334 |
if ( pos != -1 )
|
sl@0
|
335 |
{
|
sl@0
|
336 |
fPos = size_t(pos);
|
sl@0
|
337 |
if ( pos == 0 )
|
sl@0
|
338 |
gTestController.SetCurrentTestName("single insertion at begin()");
|
sl@0
|
339 |
else
|
sl@0
|
340 |
gTestController.SetCurrentTestName("single insertion at end()");
|
sl@0
|
341 |
}
|
sl@0
|
342 |
else
|
sl@0
|
343 |
gTestController.SetCurrentTestName("single insertion at random position");
|
sl@0
|
344 |
}
|
sl@0
|
345 |
|
sl@0
|
346 |
void operator()( C& c ) const
|
sl@0
|
347 |
{
|
sl@0
|
348 |
prepare_insert_n( c, (size_t)1 );
|
sl@0
|
349 |
typename C::iterator pos = c.begin();
|
sl@0
|
350 |
EH_STD::advance( pos, size_t(fPos) );
|
sl@0
|
351 |
c.insert( pos, fInsVal );
|
sl@0
|
352 |
|
sl@0
|
353 |
// Prevent simulated failures during verification
|
sl@0
|
354 |
gTestController.CancelFailureCountdown();
|
sl@0
|
355 |
// Success. Check results.
|
sl@0
|
356 |
VerifyInsertion( original, c, &fInsVal, 1+&fInsVal, fPos );
|
sl@0
|
357 |
}
|
sl@0
|
358 |
private:
|
sl@0
|
359 |
typename C::value_type fInsVal;
|
sl@0
|
360 |
const C& original;
|
sl@0
|
361 |
size_t fPos;
|
sl@0
|
362 |
};
|
sl@0
|
363 |
|
sl@0
|
364 |
template <class C>
|
sl@0
|
365 |
struct test_insert_n
|
sl@0
|
366 |
{
|
sl@0
|
367 |
test_insert_n( const C& orig, size_t insCnt, int pos =-1 )
|
sl@0
|
368 |
: original( orig ), fPos( random_number( orig.size() )), fInsCnt(insCnt)
|
sl@0
|
369 |
{
|
sl@0
|
370 |
MakeRandomValue( fInsVal );
|
sl@0
|
371 |
if (pos!=-1)
|
sl@0
|
372 |
{
|
sl@0
|
373 |
fPos=size_t(pos);
|
sl@0
|
374 |
if (pos==0)
|
sl@0
|
375 |
gTestController.SetCurrentTestName("n-ary insertion at begin()");
|
sl@0
|
376 |
else
|
sl@0
|
377 |
gTestController.SetCurrentTestName("n-ary insertion at end()");
|
sl@0
|
378 |
}
|
sl@0
|
379 |
else
|
sl@0
|
380 |
gTestController.SetCurrentTestName("n-ary insertion at random position");
|
sl@0
|
381 |
}
|
sl@0
|
382 |
|
sl@0
|
383 |
void operator()( C& c ) const
|
sl@0
|
384 |
{
|
sl@0
|
385 |
prepare_insert_n( c, fInsCnt );
|
sl@0
|
386 |
typename C::iterator pos = c.begin();
|
sl@0
|
387 |
EH_STD::advance( pos, fPos );
|
sl@0
|
388 |
c.insert( pos, fInsCnt, fInsVal );
|
sl@0
|
389 |
|
sl@0
|
390 |
// Prevent simulated failures during verification
|
sl@0
|
391 |
gTestController.CancelFailureCountdown();
|
sl@0
|
392 |
// Success. Check results.
|
sl@0
|
393 |
VerifyInsertN( original, c, fInsCnt, fInsVal, fPos );
|
sl@0
|
394 |
}
|
sl@0
|
395 |
private:
|
sl@0
|
396 |
typename C::value_type fInsVal;
|
sl@0
|
397 |
const C& original;
|
sl@0
|
398 |
size_t fPos;
|
sl@0
|
399 |
size_t fInsCnt;
|
sl@0
|
400 |
};
|
sl@0
|
401 |
|
sl@0
|
402 |
template <class C>
|
sl@0
|
403 |
struct test_insert_value
|
sl@0
|
404 |
{
|
sl@0
|
405 |
test_insert_value( const C& orig )
|
sl@0
|
406 |
: original( orig )
|
sl@0
|
407 |
{
|
sl@0
|
408 |
MakeRandomValue( fInsVal );
|
sl@0
|
409 |
gTestController.SetCurrentTestName("insertion of random value");
|
sl@0
|
410 |
}
|
sl@0
|
411 |
|
sl@0
|
412 |
void operator()( C& c ) const
|
sl@0
|
413 |
{
|
sl@0
|
414 |
c.insert( fInsVal );
|
sl@0
|
415 |
|
sl@0
|
416 |
// Prevent simulated failures during verification
|
sl@0
|
417 |
gTestController.CancelFailureCountdown();
|
sl@0
|
418 |
// Success. Check results.
|
sl@0
|
419 |
VerifyInsertion( original, c, &fInsVal, 1+&fInsVal, size_t(0) );
|
sl@0
|
420 |
}
|
sl@0
|
421 |
private:
|
sl@0
|
422 |
typename C::value_type fInsVal;
|
sl@0
|
423 |
const C& original;
|
sl@0
|
424 |
};
|
sl@0
|
425 |
|
sl@0
|
426 |
template <class C>
|
sl@0
|
427 |
struct test_insert_noresize
|
sl@0
|
428 |
{
|
sl@0
|
429 |
test_insert_noresize( const C& orig )
|
sl@0
|
430 |
: original( orig )
|
sl@0
|
431 |
{
|
sl@0
|
432 |
MakeRandomValue( fInsVal );
|
sl@0
|
433 |
gTestController.SetCurrentTestName("insertion of random value without resize");
|
sl@0
|
434 |
}
|
sl@0
|
435 |
|
sl@0
|
436 |
void operator()( C& c ) const
|
sl@0
|
437 |
{
|
sl@0
|
438 |
c.insert_noresize( fInsVal );
|
sl@0
|
439 |
|
sl@0
|
440 |
// Prevent simulated failures during verification
|
sl@0
|
441 |
gTestController.CancelFailureCountdown();
|
sl@0
|
442 |
// Success. Check results.
|
sl@0
|
443 |
VerifyInsertion( original, c, &fInsVal, 1+&fInsVal, size_t(0) );
|
sl@0
|
444 |
}
|
sl@0
|
445 |
private:
|
sl@0
|
446 |
typename C::value_type fInsVal;
|
sl@0
|
447 |
const C& original;
|
sl@0
|
448 |
};
|
sl@0
|
449 |
|
sl@0
|
450 |
template <class C, class Position, class Iter>
|
sl@0
|
451 |
void do_insert_range( C& c_inst, Position offset,
|
sl@0
|
452 |
Iter first, Iter last, sequence_container_tag )
|
sl@0
|
453 |
{
|
sl@0
|
454 |
typedef typename C::iterator CIter;
|
sl@0
|
455 |
CIter pos = c_inst.begin();
|
sl@0
|
456 |
EH_STD::advance( pos, offset );
|
sl@0
|
457 |
c_inst.insert( pos, first, last );
|
sl@0
|
458 |
}
|
sl@0
|
459 |
|
sl@0
|
460 |
template <class C, class Position, class Iter>
|
sl@0
|
461 |
void do_insert_range( C& c, Position,
|
sl@0
|
462 |
Iter first, Iter last, associative_container_tag )
|
sl@0
|
463 |
{
|
sl@0
|
464 |
c.insert( first, last );
|
sl@0
|
465 |
}
|
sl@0
|
466 |
|
sl@0
|
467 |
template <class C, class Position, class Iter>
|
sl@0
|
468 |
void do_insert_range( C& c, Position, Iter first, Iter last, multiset_tag )
|
sl@0
|
469 |
{
|
sl@0
|
470 |
c.insert( first, last );
|
sl@0
|
471 |
}
|
sl@0
|
472 |
|
sl@0
|
473 |
template <class C, class Position, class Iter>
|
sl@0
|
474 |
void do_insert_range( C& c, Position, Iter first, Iter last, multimap_tag )
|
sl@0
|
475 |
{
|
sl@0
|
476 |
c.insert( first, last );
|
sl@0
|
477 |
}
|
sl@0
|
478 |
|
sl@0
|
479 |
template <class C, class Position, class Iter>
|
sl@0
|
480 |
void do_insert_range( C& c, Position, Iter first, Iter last, set_tag )
|
sl@0
|
481 |
{
|
sl@0
|
482 |
c.insert( first, last );
|
sl@0
|
483 |
}
|
sl@0
|
484 |
|
sl@0
|
485 |
template <class C, class Position, class Iter>
|
sl@0
|
486 |
void do_insert_range( C& c, Position, Iter first, Iter last, map_tag )
|
sl@0
|
487 |
{
|
sl@0
|
488 |
c.insert( first, last );
|
sl@0
|
489 |
}
|
sl@0
|
490 |
|
sl@0
|
491 |
/*
|
sl@0
|
492 |
template <class C, class Iter>
|
sl@0
|
493 |
void prepare_insert_range( C&, size_t, Iter, Iter) {}
|
sl@0
|
494 |
*/
|
sl@0
|
495 |
|
sl@0
|
496 |
template <class C, class Iter>
|
sl@0
|
497 |
struct test_insert_range
|
sl@0
|
498 |
{
|
sl@0
|
499 |
test_insert_range( const C& orig, Iter first, Iter last, int pos=-1 )
|
sl@0
|
500 |
: fFirst( first ),
|
sl@0
|
501 |
fLast( last ),
|
sl@0
|
502 |
original( orig ),
|
sl@0
|
503 |
fPos( random_number( orig.size() ))
|
sl@0
|
504 |
{
|
sl@0
|
505 |
gTestController.SetCurrentTestName("range insertion");
|
sl@0
|
506 |
if ( pos != -1 )
|
sl@0
|
507 |
{
|
sl@0
|
508 |
fPos = size_t(pos);
|
sl@0
|
509 |
if ( pos == 0 )
|
sl@0
|
510 |
gTestController.SetCurrentTestName("range insertion at begin()");
|
sl@0
|
511 |
else
|
sl@0
|
512 |
gTestController.SetCurrentTestName("range insertion at end()");
|
sl@0
|
513 |
}
|
sl@0
|
514 |
else
|
sl@0
|
515 |
gTestController.SetCurrentTestName("range insertion at random position");
|
sl@0
|
516 |
}
|
sl@0
|
517 |
|
sl@0
|
518 |
void operator()( C& c ) const
|
sl@0
|
519 |
{
|
sl@0
|
520 |
// prepare_insert_range( c, fPos, fFirst, fLast );
|
sl@0
|
521 |
do_insert_range( c, fPos, fFirst, fLast, container_category(c) );
|
sl@0
|
522 |
|
sl@0
|
523 |
// Prevent simulated failures during verification
|
sl@0
|
524 |
gTestController.CancelFailureCountdown();
|
sl@0
|
525 |
// Success. Check results.
|
sl@0
|
526 |
VerifyInsertion( original, c, fFirst, fLast, fPos );
|
sl@0
|
527 |
}
|
sl@0
|
528 |
private:
|
sl@0
|
529 |
Iter fFirst, fLast;
|
sl@0
|
530 |
const C& original;
|
sl@0
|
531 |
size_t fPos;
|
sl@0
|
532 |
};
|
sl@0
|
533 |
|
sl@0
|
534 |
template <class C, class Iter>
|
sl@0
|
535 |
test_insert_range<C, Iter> insert_range_tester( const C& orig, const Iter& first, const Iter& last )
|
sl@0
|
536 |
{
|
sl@0
|
537 |
return test_insert_range<C, Iter>( orig, first, last );
|
sl@0
|
538 |
}
|
sl@0
|
539 |
|
sl@0
|
540 |
template <class C, class Iter>
|
sl@0
|
541 |
test_insert_range<C, Iter> insert_range_at_begin_tester( const C& orig, const Iter& first, const Iter& last )
|
sl@0
|
542 |
{
|
sl@0
|
543 |
return test_insert_range<C, Iter>( orig, first, last , 0);
|
sl@0
|
544 |
}
|
sl@0
|
545 |
|
sl@0
|
546 |
template <class C, class Iter>
|
sl@0
|
547 |
test_insert_range<C, Iter> insert_range_at_end_tester( const C& orig, const Iter& first, const Iter& last )
|
sl@0
|
548 |
{
|
sl@0
|
549 |
return test_insert_range<C, Iter>( orig, first, last , (int)orig.size());
|
sl@0
|
550 |
}
|
sl@0
|
551 |
|
sl@0
|
552 |
#endif // test_insert_H_
|