1#include <vector>
2#include <algorithm>
3#include <vector>
4#include <queue>
5
6#if 0 /* temporary: investigation of problem with swap */
7#include <iostream>
8#include <typeinfo>
9#endif
10
11#include "cppunit/cppunit_proxy.h"
12
13#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
14using namespace std;
15#endif
16
17//
18// TestCase class
19//
20class SwapTest : public CPPUNIT_NS::TestCase
21{
22  CPPUNIT_TEST_SUITE(SwapTest);
23  CPPUNIT_TEST(swap1);
24  CPPUNIT_TEST(swprnge1);
25  CPPUNIT_TEST(swap_container_non_spec);
26#if defined (STLPORT) && \
27   !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) && !defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
28  CPPUNIT_IGNORE;
29#endif
30  CPPUNIT_TEST(swap_container_spec);
31  CPPUNIT_TEST_SUITE_END();
32
33protected:
34  void swap1();
35  void swprnge1();
36  void swap_container_non_spec();
37  void swap_container_spec();
38};
39
40CPPUNIT_TEST_SUITE_REGISTRATION(SwapTest);
41
42//
43// tests implementation
44//
45void SwapTest::swap1()
46{
47  int a = 42;
48  int b = 19;
49  swap(a, b);
50
51  CPPUNIT_ASSERT(a==19);
52  CPPUNIT_ASSERT(b==42);
53}
54
55void SwapTest::swprnge1()
56{
57  char word1[] = "World";
58  char word2[] = "Hello";
59  swap_ranges((char*)word1, (char*)word1 + ::strlen(word1), (char*)word2);
60  CPPUNIT_ASSERT(!strcmp(word1, "Hello"));
61  CPPUNIT_ASSERT(!strcmp(word2, "World"));
62}
63
64class Obj
65{
66  public:
67    Obj() :
68        v( 0 )
69      { }
70    Obj( const Obj& ) :
71        v( 1 )
72      { }
73
74    Obj& operator =( const Obj& )
75      { v = 2; return *this; }
76
77    int v;
78};
79
80/*
81 * Following two tests check the corectness of specialization of swap():
82 * for containers with container::swap method swap( a, b ) should
83 * use a.swap( b ), but don't try to do this substitution for container
84 * without swap method (in this case swap should be made via explicit members
85 * exchange; this assume usage of temporary object)
86 *
87 */
88void SwapTest::swap_container_non_spec()
89{
90  queue<Obj> v1;
91  queue<Obj> v2;
92
93  v1.push( Obj() );
94  v1.back().v = -1;
95  v1.push( Obj() );
96  v1.back().v = -2;
97
98  v2.push( Obj() );
99  v2.back().v = 10;
100  v2.push( Obj() );
101  v2.back().v = 11;
102  v2.push( Obj() );
103  v2.back().v = 12;
104
105  CPPUNIT_CHECK( v1.size() == 2 );
106  CPPUNIT_CHECK( v2.size() == 3 );
107
108  swap( v1, v2 ); // this shouldn't try make it as v1.swap( v2 ), no queue::swap method!
109
110  CPPUNIT_CHECK( v1.size() == 3 );
111  CPPUNIT_CHECK( v2.size() == 2 );
112
113  // either copy constructor or assignment operator
114  CPPUNIT_CHECK( v1.front().v == 1 || v1.front().v == 2 );
115  CPPUNIT_CHECK( v1.back().v == 1 || v1.back().v == 2 );
116  CPPUNIT_CHECK( v2.front().v == 1 || v2.front().v == 2 );
117  CPPUNIT_CHECK( v2.back().v == 1 || v2.back().v == 2 );
118}
119
120void SwapTest::swap_container_spec()
121{
122#if 0 /* temporary: investigation of problem with swap */
123  if ( typeid(/* _STLP_PRIV */ _SwapImplemented<vector<Obj> >::_Ret) == typeid(_STLP_PRIV __false_type) ) {
124    cerr << "false type" << endl;
125  } else if ( typeid(/* _STLP_PRIV */ _SwapImplemented<vector<Obj> >::_Ret) == typeid(_STLP_PRIV __true_type) ) {
126    cerr << "true type" << endl;
127  } else {
128    cerr << "unknown type" << endl;
129  }
130#endif /* end of temporary */
131#if !defined (STLPORT) || \
132     defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) || defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
133  vector<Obj> v1;
134  vector<Obj> v2;
135
136  v1.push_back( Obj() );
137  v1.push_back( Obj() );
138
139  v1[0].v = -1;
140  v1[1].v = -2;
141
142  v2.push_back( Obj() );
143  v2.push_back( Obj() );
144  v2.push_back( Obj() );
145
146  v2[0].v = 10;
147  v2[1].v = 11;
148  v2[2].v = 12;
149
150  CPPUNIT_CHECK( v1.size() == 2 );
151  CPPUNIT_CHECK( v2.size() == 3 );
152
153  swap( v1, v2 ); // this should has effect v1.swap( v2 )
154
155  CPPUNIT_CHECK( v1.size() == 3 );
156  CPPUNIT_CHECK( v2.size() == 2 );
157
158  CPPUNIT_CHECK( v1[0].v == 10 );
159  CPPUNIT_CHECK( v1[1].v == 11 );
160  CPPUNIT_CHECK( v1[2].v == 12 );
161
162  CPPUNIT_CHECK( v2[0].v == -1 );
163  CPPUNIT_CHECK( v2[1].v == -2 );
164#endif
165}
166