Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * containers/test_iterators.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2007 Roman Dementiev <dementiev@ira.uka.de> 00007 * Copyright (C) 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 00012 **************************************************************************/ 00013 00014 #include <cassert> 00015 #include <cstring> 00016 #include <deque> 00017 #include <map> 00018 #include <vector> 00019 #include <stxxl.h> 00020 00021 00022 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) 00023 00024 template <typename T> 00025 const char * _() 00026 { 00027 const char * start = strchr(STXXL_PRETTY_FUNCTION_NAME, '['); 00028 if (start == NULL) 00029 return "unknown"; 00030 else 00031 return start; 00032 } 00033 00034 template <typename I> 00035 void dump_iterator_info(I &) 00036 { 00037 STXXL_MSG(STXXL_PRETTY_FUNCTION_NAME); 00038 STXXL_MSG(" category: " << _<typename std::iterator_traits<I>::iterator_category>()); 00039 STXXL_MSG(" value_type: " << _<typename std::iterator_traits<I>::value_type>()); 00040 STXXL_MSG(" difference_type: " << _<typename std::iterator_traits<I>::difference_type>()); 00041 STXXL_MSG(" pointer: " << _<typename std::iterator_traits<I>::pointer>()); 00042 STXXL_MSG(" reference: " << _<typename std::iterator_traits<I>::reference>()); 00043 } 00044 00045 template <typename C> 00046 void dump_container_info(C &) 00047 { 00048 STXXL_MSG(STXXL_PRETTY_FUNCTION_NAME); 00049 STXXL_MSG(" value_type: " << _<typename C::value_type>()); 00050 STXXL_MSG(" size_type: " << _<typename C::size_type>()); 00051 STXXL_MSG(" difference_type: " << _<typename C::difference_type>()); 00052 STXXL_MSG(" pointer: " << _<typename C::pointer>()); 00053 STXXL_MSG(" const_pointer: " << _<typename C::const_pointer>()); 00054 STXXL_MSG(" reference: " << _<typename C::reference>()); 00055 STXXL_MSG(" const_reference: " << _<typename C::const_reference>()); 00056 STXXL_MSG(" iterator: " << _<typename C::iterator>()); 00057 STXXL_MSG(" const_iterator: " << _<typename C::const_iterator>()); 00058 } 00059 00060 template <typename T> 00061 struct modify 00062 { 00063 void operator () (T & obj) const 00064 { 00065 ++obj; 00066 } 00067 }; 00068 00069 template <typename Iterator> 00070 bool test_inc_dec(Iterator it) 00071 { 00072 Iterator i = it; 00073 00074 ++i; 00075 i++; 00076 --i; 00077 i--; 00078 00079 assert(it == i); 00080 return it == i; 00081 } 00082 00083 template <typename Iterator> 00084 bool test_inc_dec_random(Iterator it) 00085 { 00086 Iterator i = it; 00087 00088 ++i; 00089 i = i + 2; 00090 i++; 00091 i += 3; 00092 --i; 00093 i = i - 3; 00094 i--; 00095 i -= 2; 00096 00097 assert(it == i); 00098 return it == i; 00099 } 00100 00101 template <typename IteratorA, typename IteratorB, typename Category> 00102 struct test_comparison_lt_gt 00103 { 00104 void operator () (IteratorA, IteratorB) 00105 { 00106 // operators <, <=, >=, > are not available in all iterator categories 00107 } 00108 }; 00109 00110 template <typename IteratorA, typename IteratorB> 00111 struct test_comparison_lt_gt<IteratorA, IteratorB, std::random_access_iterator_tag> 00112 { 00113 void operator () (IteratorA a, IteratorB b) 00114 { 00115 a < b; 00116 a <= b; 00117 a > b; 00118 a >= b; 00119 00120 b < a; 00121 b <= a; 00122 b > a; 00123 b >= a; 00124 } 00125 }; 00126 00127 template <typename IteratorA, typename IteratorB> 00128 void test_comparison(IteratorA a, IteratorB b) 00129 { 00130 a == b; 00131 a != b; 00132 00133 b == a; 00134 b != a; 00135 00136 test_comparison_lt_gt<IteratorA, IteratorB, typename std::iterator_traits<IteratorA>::iterator_category>() (a, b); 00137 } 00138 00139 template <typename Iterator> 00140 void test_operators(Iterator it) 00141 { 00142 *it; 00143 it.operator -> (); 00144 test_comparison(it, it); 00145 } 00146 00147 template <typename svt> 00148 void test(svt & sv) 00149 { 00150 dump_container_info(sv); 00151 00152 typedef const svt csvt; 00153 typedef typename svt::value_type value_type; 00154 00155 sv[0] = 108; 00156 00157 typename svt::iterator svi = sv.begin(); 00158 dump_iterator_info(svi); 00159 modify<value_type>() (*svi); 00160 00161 typename svt::const_iterator svci = sv.begin(); 00162 dump_iterator_info(svci); 00163 //modify<value_type>()(*svci); // read-only 00164 00165 typename csvt::iterator xsvi = sv.begin(); 00166 modify<value_type>() (*xsvi); 00167 00168 // test assignment 00169 svci = xsvi; 00170 //xsvi = svci; // not allowed 00171 00172 typename csvt::const_iterator xsvci = sv.begin(); 00173 //modify<value_type>()(*xsvci); // read-only 00174 00175 // test comparison between const and non-const iterators 00176 test_comparison(svci, xsvi); 00177 00178 // test increment/decrement 00179 test_inc_dec(svi); 00180 test_inc_dec(svci); 00181 test_inc_dec(xsvi); 00182 test_inc_dec(xsvci); 00183 00184 // test operators 00185 test_operators(svi); 00186 test_operators(svci); 00187 test_operators(xsvi); 00188 test_operators(xsvci); 00189 00190 // test forward iteration 00191 for (typename svt::iterator i = sv.begin(); i != sv.end(); ++i) ; 00192 00193 /////////////////////////////////////////////////////////////////////////// 00194 00195 csvt & csv = sv; 00196 //csv[0] = 108; // read-only 00197 00198 //typename csvt::iterator csvi = csv.begin(); // read-only 00199 //modify<value_type>()(*csvi); // read-only 00200 00201 typename csvt::const_iterator csvci = csv.begin(); 00202 //modify<value_type>()(*csvci); // read-only 00203 00204 //typename svt::iterator xcsvi = csv.begin(); // read-only 00205 //modify<value_type>()(*xcsvi); // read-only 00206 00207 typename svt::const_iterator xcsvci = csv.begin(); 00208 //modify<value_type>()(*csvci); // read-only 00209 00210 // test increment/decrement 00211 test_inc_dec(csvci); 00212 test_inc_dec(xcsvci); 00213 00214 // test operators 00215 test_operators(csvci); 00216 test_operators(xcsvci); 00217 00218 // test forward iteration 00219 for (typename svt::const_iterator ci = sv.begin(); ci != sv.end(); ++ci) ; 00220 } 00221 00222 template <typename svt> 00223 void test_reverse(svt & sv) 00224 { 00225 dump_container_info(sv); 00226 00227 typedef const svt csvt; 00228 typedef typename svt::value_type value_type; 00229 00230 sv[0] = 108; 00231 00232 typename svt::reverse_iterator svi = sv.rbegin(); 00233 dump_iterator_info(svi); 00234 modify<value_type>() (*svi); 00235 00236 typename svt::const_reverse_iterator svci = sv.rbegin(); 00237 dump_iterator_info(svci); 00238 //modify<value_type>()(*svci); // read-only 00239 00240 typename csvt::reverse_iterator xsvi = sv.rbegin(); 00241 modify<value_type>() (*xsvi); 00242 00243 // test assignment 00244 svci = xsvi; 00245 //xsvi = svci; // not allowed 00246 00247 typename csvt::const_reverse_iterator xsvci = sv.rbegin(); 00248 //modify<value_type>()(*xsvci); // read-only 00249 00250 #if !defined(__GNUG__) || (GCC_VERSION >= 40100) 00251 // test comparison between const and non-const iterators 00252 test_comparison(svci, xsvi); 00253 #endif 00254 00255 // test increment/decrement 00256 test_inc_dec(svi); 00257 test_inc_dec(svci); 00258 test_inc_dec(xsvi); 00259 test_inc_dec(xsvci); 00260 00261 // test operators 00262 test_operators(svi); 00263 test_operators(svci); 00264 test_operators(xsvi); 00265 test_operators(xsvci); 00266 00267 // test forward iteration 00268 for (typename svt::reverse_iterator i = sv.rbegin(); i != sv.rend(); ++i) ; 00269 00270 /////////////////////////////////////////////////////////////////////////// 00271 00272 csvt & csv = sv; 00273 //csv[0] = 108; // read-only 00274 00275 //typename csvt::reverse_iterator csvi = csv.rbegin(); // read-only 00276 //modify<value_type>()(*csvi); // read-only 00277 00278 typename csvt::const_reverse_iterator csvci = csv.rbegin(); 00279 //modify<value_type>()(*csvci); // read-only 00280 00281 //typename svt::reverse_iterator xcsvi = csv.rbegin(); // read-only 00282 //modify<value_type>()(*xcsvi); // read-only 00283 00284 typename svt::const_reverse_iterator xcsvci = csv.rbegin(); 00285 //modify<value_type>()(*csvci); // read-only 00286 00287 // test increment/decrement 00288 test_inc_dec(csvci); 00289 test_inc_dec(xcsvci); 00290 00291 // test operators 00292 test_operators(csvci); 00293 test_operators(xcsvci); 00294 00295 // test forward iteration 00296 #if !defined(__GNUG__) || (GCC_VERSION >= 40100) 00297 for (typename svt::const_reverse_iterator ci = sv.rbegin(); ci != sv.rend(); ++ci) ; 00298 #else 00299 for (typename svt::const_reverse_iterator ci = sv.rbegin(); ci != typename svt::const_reverse_iterator(sv.rend()); ++ci) ; 00300 #endif 00301 } 00302 00303 template <typename svt> 00304 void test_random_access(svt & sv) 00305 { 00306 typename svt::const_iterator svci = sv.begin(); 00307 typename svt::iterator xsvi = sv.begin(); 00308 00309 // test subtraction of const and non-const iterators 00310 svci - xsvi; 00311 xsvi - svci; 00312 00313 // bracket operators 00314 svci[0]; 00315 xsvi[0]; 00316 //svci[0] = 1; // read-only 00317 xsvi[0] = 1; 00318 00319 // test +, -, +=, -= 00320 test_inc_dec_random(svci); 00321 test_inc_dec_random(xsvi); 00322 } 00323 00324 template <typename svt> 00325 void test_random_access_reverse(svt & sv) 00326 { 00327 typename svt::const_reverse_iterator svcri = sv.rbegin(); 00328 typename svt::reverse_iterator xsvri = sv.rbegin(); 00329 00330 #if !defined(__GNUG__) || (GCC_VERSION >= 40100) 00331 // test subtraction of const and non-const iterators 00332 svcri - xsvri; 00333 xsvri - svcri; 00334 #endif 00335 00336 // bracket operators 00337 svcri[0]; 00338 xsvri[0]; 00339 //svcri[0] = 1; // read-only 00340 xsvri[0] = 1; 00341 00342 // test +, -, +=, -= 00343 test_inc_dec_random(svcri); 00344 test_inc_dec_random(xsvri); 00345 } 00346 00347 00348 typedef float key_type; 00349 typedef double data_type; 00350 00351 struct cmp : public std::less<key_type> 00352 { 00353 static key_type min_value() 00354 { 00355 return (std::numeric_limits<key_type>::min)(); 00356 } 00357 static key_type max_value() 00358 { 00359 return (std::numeric_limits<key_type>::max)(); 00360 } 00361 }; 00362 00363 00364 template <> 00365 struct modify<std::pair<const key_type, data_type> > 00366 { 00367 void operator () (std::pair<const key_type, data_type> & obj) const 00368 { 00369 ++(obj.second); 00370 } 00371 }; 00372 00373 int main() 00374 { 00375 std::vector<double> V(8); 00376 test(V); 00377 test_reverse(V); 00378 test_random_access(V); 00379 test_random_access_reverse(V); 00380 00381 stxxl::vector<double> Vector(8); 00382 test(Vector); 00383 test_reverse(Vector); 00384 test_random_access(Vector); 00385 test_random_access_reverse(Vector); 00386 00387 std::map<key_type, data_type, cmp> M; 00388 M[4] = 8; 00389 M[15] = 16; 00390 M[23] = 42; 00391 test(M); 00392 test_reverse(M); 00393 00394 #if !defined(__GNUG__) || (GCC_VERSION >= 30400) 00395 typedef stxxl::map<key_type, data_type, cmp, 4096, 4096> map_type; 00396 map_type Map(4096 * 10, 4096 * 10); 00397 Map[4] = 8; 00398 Map[15] = 16; 00399 Map[23] = 42; 00400 test(Map); 00401 test_reverse(Map); 00402 #endif 00403 00404 std::deque<double> D(8); 00405 test(D); 00406 test_reverse(D); 00407 test_random_access(D); 00408 test_random_access_reverse(D); 00409 00410 stxxl::deque<double> Deque(8); 00411 test(Deque); 00412 test_reverse(Deque); 00413 test_random_access(Deque); 00414 test_random_access_reverse(Deque); 00415 00416 return 0; 00417 } 00418 00419 // vim: et:ts=4:sw=4