PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/libs/iterator/test/iterator_adaptor_test.cpp

http://hadesmem.googlecode.com/
C++ | 337 lines | 259 code | 56 blank | 22 comment | 7 complexity | 18c3c15f350d54e687a9cb5b61f8f78f MD5 | raw file
  1//  (C) Copyright Thomas Witt 2003.
  2//  Distributed under the Boost Software License, Version 1.0. (See
  3//  accompanying file LICENSE_1_0.txt or copy at
  4//  http://www.boost.org/LICENSE_1_0.txt)
  5
  6//  See http://www.boost.org for most recent version including documentation.
  7
  8#include <boost/config.hpp>
  9#include <iostream>
 10
 11#include <algorithm>
 12#include <functional>
 13#include <numeric>
 14
 15#include <boost/iterator/iterator_adaptor.hpp>
 16#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
 17# include <boost/iterator/is_readable_iterator.hpp>
 18# include <boost/iterator/is_lvalue_iterator.hpp>
 19#endif 
 20#include <boost/pending/iterator_tests.hpp>
 21
 22# include <boost/type_traits/broken_compiler_spec.hpp>
 23
 24# include <boost/detail/lightweight_test.hpp>
 25
 26#include <stdlib.h>
 27#include <vector>
 28#include <deque>
 29#include <set>
 30#include <list>
 31
 32#include "static_assert_same.hpp"
 33
 34#include <boost/iterator/detail/config_def.hpp>
 35
 36using boost::dummyT;
 37
 38struct mult_functor {
 39  typedef int result_type;
 40  typedef int argument_type;
 41  // Functors used with transform_iterator must be
 42  // DefaultConstructible, as the transform_iterator must be
 43  // DefaultConstructible to satisfy the requirements for
 44  // TrivialIterator.
 45  mult_functor() { }
 46  mult_functor(int aa) : a(aa) { }
 47  int operator()(int b) const { return a * b; }
 48  int a;
 49};
 50
 51template <class Pair>
 52struct select1st_ 
 53  : public std::unary_function<Pair, typename Pair::first_type>
 54{
 55  const typename Pair::first_type& operator()(const Pair& x) const {
 56    return x.first;
 57  }
 58  typename Pair::first_type& operator()(Pair& x) const {
 59    return x.first;
 60  }
 61};
 62
 63struct one_or_four {
 64  bool operator()(dummyT x) const {
 65    return x.foo() == 1 || x.foo() == 4;
 66  }
 67};
 68
 69typedef std::deque<int> storage;
 70typedef std::deque<int*> pointer_deque;
 71typedef std::set<storage::iterator> iterator_set;
 72
 73template <class T> struct foo;
 74
 75void blah(int) { }
 76
 77struct my_gen
 78{
 79  typedef int result_type;
 80  my_gen() : n(0) { }
 81  int operator()() { return ++n; }
 82  int n;
 83};
 84
 85template <class V>
 86struct ptr_iterator
 87  : boost::iterator_adaptor<
 88        ptr_iterator<V>
 89      , V*
 90      , V
 91      , boost::random_access_traversal_tag
 92#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
 93      , V&
 94#endif 
 95   >
 96{
 97private:
 98  typedef boost::iterator_adaptor<
 99        ptr_iterator<V>
100      , V*
101      , V
102      , boost::random_access_traversal_tag
103#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
104      , V&
105#endif 
106    > super_t;
107    
108public:
109  ptr_iterator() { }
110  ptr_iterator(V* d) : super_t(d) { }
111
112  template <class V2>
113  ptr_iterator(
114        const ptr_iterator<V2>& x
115      , typename boost::enable_if_convertible<V2*, V*>::type* = 0
116  )
117    : super_t(x.base())
118  {}
119};
120
121// Non-functional iterator for category modification checking
122template <class Iter, class Traversal>
123struct modify_traversal
124  :  boost::iterator_adaptor<
125         modify_traversal<Iter, Traversal>
126       , Iter
127       , boost::use_default
128       , Traversal
129     >
130{};
131  
132template <class T>
133struct fwd_iterator
134  : boost::iterator_adaptor<
135        fwd_iterator<T>
136      , boost::forward_iterator_archetype<T>
137    >
138{
139private:
140  typedef boost::iterator_adaptor<
141        fwd_iterator<T>
142      , boost::forward_iterator_archetype<T>
143  > super_t;
144    
145public:
146  fwd_iterator() { }
147  fwd_iterator(boost::forward_iterator_archetype<T> d) : super_t(d) { }
148};
149
150template <class T>
151struct in_iterator
152  : boost::iterator_adaptor<
153        in_iterator<T>
154      , boost::input_iterator_archetype_no_proxy<T>
155    >
156{
157private:
158  typedef boost::iterator_adaptor<
159        in_iterator<T>
160      , boost::input_iterator_archetype_no_proxy<T>
161  > super_t;
162    
163public:
164  in_iterator() { }
165  in_iterator(boost::input_iterator_archetype_no_proxy<T> d) : super_t(d) { }
166};
167
168template <class Iter>
169struct constant_iterator
170  : boost::iterator_adaptor<
171        constant_iterator<Iter>
172      , Iter
173      , typename std::iterator_traits<Iter>::value_type const
174    >
175{
176    typedef boost::iterator_adaptor<
177        constant_iterator<Iter>
178      , Iter
179      , typename std::iterator_traits<Iter>::value_type const
180    > base_t;
181    
182  constant_iterator() {}
183  constant_iterator(Iter it)
184    : base_t(it) {}
185};
186
187char (& traversal2(boost::incrementable_traversal_tag) )[1];
188char (& traversal2(boost::single_pass_traversal_tag  ) )[2];
189char (& traversal2(boost::forward_traversal_tag      ) )[3];
190char (& traversal2(boost::bidirectional_traversal_tag) )[4];
191char (& traversal2(boost::random_access_traversal_tag) )[5];
192
193template <class Cat>
194struct traversal3
195{
196    static typename boost::iterator_category_to_traversal<Cat>::type x;
197    BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
198    typedef char (&type)[value];
199};
200
201template <class Cat>
202typename traversal3<Cat>::type traversal(Cat);
203
204template <class Iter, class Trav>
205int static_assert_traversal(Iter* = 0, Trav* = 0)
206{
207    typedef typename boost::iterator_category_to_traversal<
208        BOOST_DEDUCED_TYPENAME Iter::iterator_category
209        >::type t2;
210
211    return static_assert_same<Trav,t2>::value;
212}
213
214int
215main()
216{
217  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
218                     dummyT(3), dummyT(4), dummyT(5) };
219  const int N = sizeof(array)/sizeof(dummyT);
220
221  // sanity check, if this doesn't pass the test is buggy
222  boost::random_access_iterator_test(array, N, array);
223
224  // Test the iterator_adaptor
225  {
226    ptr_iterator<dummyT> i(array);
227    boost::random_access_iterator_test(i, N, array);
228    
229    ptr_iterator<const dummyT> j(array);
230    boost::random_access_iterator_test(j, N, array);
231    boost::const_nonconst_iterator_test(i, ++j);
232  }
233
234  int test;
235  // Test the iterator_traits
236  {
237    // Test computation of defaults
238    typedef ptr_iterator<int> Iter1;
239    // don't use std::iterator_traits here to avoid VC++ problems
240    test = static_assert_same<Iter1::value_type, int>::value;
241    test = static_assert_same<Iter1::reference, int&>::value;
242    test = static_assert_same<Iter1::pointer, int*>::value;
243    test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
244#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
245    BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
246#endif 
247  }
248  
249  {  
250    // Test computation of default when the Value is const
251    typedef ptr_iterator<int const> Iter1;
252    test = static_assert_same<Iter1::value_type, int>::value;
253    test = static_assert_same<Iter1::reference, const int&>::value;
254    
255#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
256    BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
257# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
258    BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
259# endif 
260#endif
261
262#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
263    test = static_assert_same<Iter1::pointer, int const*>::value;
264#endif 
265  }
266
267  {
268    // Test constant iterator idiom
269    typedef ptr_iterator<int> BaseIter;
270    typedef constant_iterator<BaseIter> Iter;
271
272    test = static_assert_same<Iter::value_type, int>::value;
273    test = static_assert_same<Iter::reference, int const&>::value;
274#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
275    test = static_assert_same<Iter::pointer, int const*>::value;
276#endif 
277
278#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
279    BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
280    BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
281#endif 
282    
283    typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
284
285    static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
286    static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
287  }
288  
289  // Test the iterator_adaptor
290  {
291    ptr_iterator<dummyT> i(array);
292    boost::random_access_iterator_test(i, N, array);
293    
294    ptr_iterator<const dummyT> j(array);
295    boost::random_access_iterator_test(j, N, array);
296    boost::const_nonconst_iterator_test(i, ++j);
297  }
298
299  // check operator-> with a forward iterator
300  {
301    boost::forward_iterator_archetype<dummyT> forward_iter;
302
303    typedef fwd_iterator<dummyT> adaptor_type;
304
305    adaptor_type i(forward_iter);
306    int zero = 0;
307    if (zero) // don't do this, just make sure it compiles
308      BOOST_TEST((*i).m_x == i->foo());      
309  }
310  
311  // check operator-> with an input iterator
312  {
313    boost::input_iterator_archetype_no_proxy<dummyT> input_iter;
314    typedef in_iterator<dummyT> adaptor_type;
315    adaptor_type i(input_iter);
316    int zero = 0;
317    if (zero) // don't do this, just make sure it compiles
318      BOOST_TEST((*i).m_x == i->foo());      
319  }
320
321  // check that base_type is correct
322  {
323    // Test constant iterator idiom
324    typedef ptr_iterator<int> BaseIter;
325
326    test = static_assert_same<BaseIter::base_type,int*>::value;
327    test = static_assert_same<constant_iterator<BaseIter>::base_type,BaseIter>::value;
328
329    typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
330
331    test = static_assert_same<IncrementableIter::base_type,BaseIter>::value;
332  }
333
334  std::cout << "test successful " << std::endl;
335  (void)test;
336  return boost::report_errors();
337}