Stxxl  1.4.0
containers/test_iterators.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines