Example #1
0
int
main()
{
  using boost::dummyT;
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
                     dummyT(3), dummyT(4), dummyT(5) };
  typedef boost::iterator_adaptor<dummyT*, 
    boost::default_iterator_policies, dummyT> my_iter;
  my_iter mi(array);

  {
    typedef boost::iterator_adaptor<my_iter, boost::default_iterator_policies,
      boost::reference_is<dummyT>,
      boost::iterator_category_is<std::input_iterator_tag> > iter_type;

    BOOST_STATIC_ASSERT((boost::is_same<iter_type::iterator_category*,
       std::input_iterator_tag*>::value));

    BOOST_STATIC_ASSERT(( ! boost::is_convertible<iter_type::iterator_category*,
       std::forward_iterator_tag*>::value));

    iter_type i(mi);
    boost::input_iterator_test(i, dummyT(0), dummyT(1));
  }
  {
    typedef boost::iterator_adaptor<dummyT*,
      boost::default_iterator_policies,
      boost::value_type_is<dummyT>,
      boost::reference_is<const dummyT&>,
      boost::pointer_is<const dummyT*> ,
      boost::iterator_category_is<std::forward_iterator_tag>,
      boost::difference_type_is<std::ptrdiff_t> > adaptor_type;

    adaptor_type i(array);

    boost::input_iterator_test(i, dummyT(0), dummyT(1));
    int zero = 0;
    if (zero) // don't do this, just make sure it compiles
      assert((*i).m_x == i->foo());      
  }

  return 0;
}
int
main()
{
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
                     dummyT(3), dummyT(4), dummyT(5) };
  const int N = sizeof(array)/sizeof(dummyT);

  // sanity check, if this doesn't pass the test is buggy
  boost::random_access_iterator_test(array, N, array);

  // Test the iterator_adaptor
  {
    ptr_iterator<dummyT> i(array);
    boost::random_access_iterator_test(i, N, array);
    
    ptr_iterator<const dummyT> j(array);
    boost::random_access_iterator_test(j, N, array);
    boost::const_nonconst_iterator_test(i, ++j);
  }

  int test;
  // Test the iterator_traits
  {
    // Test computation of defaults
    typedef ptr_iterator<int> Iter1;
    // don't use std::iterator_traits here to avoid VC++ problems
    test = static_assert_same<Iter1::value_type, int>::value;
    test = static_assert_same<Iter1::reference, int&>::value;
    test = static_assert_same<Iter1::pointer, int*>::value;
    test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
    BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
#endif 
  }
  
  {  
    // Test computation of default when the Value is const
    typedef ptr_iterator<int const> Iter1;
    test = static_assert_same<Iter1::value_type, int>::value;
    test = static_assert_same<Iter1::reference, const int&>::value;
    
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
    BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
    BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
# endif 
#endif

#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
    test = static_assert_same<Iter1::pointer, int const*>::value;
#endif 
  }

  {
    // Test constant iterator idiom
    typedef ptr_iterator<int> BaseIter;
    typedef constant_iterator<BaseIter> Iter;

    test = static_assert_same<Iter::value_type, int>::value;
    test = static_assert_same<Iter::reference, int const&>::value;
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
    test = static_assert_same<Iter::pointer, int const*>::value;
#endif 

#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
    BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
    BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
#endif 
    
    typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;

    static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
    static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
  }
  
  // Test the iterator_adaptor
  {
    ptr_iterator<dummyT> i(array);
    boost::random_access_iterator_test(i, N, array);
    
    ptr_iterator<const dummyT> j(array);
    boost::random_access_iterator_test(j, N, array);
    boost::const_nonconst_iterator_test(i, ++j);
  }

  // check operator-> with a forward iterator
  {
    boost::forward_iterator_archetype<dummyT> forward_iter;

    typedef fwd_iterator<dummyT> adaptor_type;

    adaptor_type i(forward_iter);
    int zero = 0;
    if (zero) // don't do this, just make sure it compiles
      assert((*i).m_x == i->foo());      
  }
  
  // check operator-> with an input iterator
  {
    boost::input_iterator_archetype_no_proxy<dummyT> input_iter;
    typedef in_iterator<dummyT> adaptor_type;
    adaptor_type i(input_iter);
    int zero = 0;
    if (zero) // don't do this, just make sure it compiles
      assert((*i).m_x == i->foo());      
  }

  // check that base_type is correct
  {
    // Test constant iterator idiom
    typedef ptr_iterator<int> BaseIter;

    test = static_assert_same<BaseIter::base_type,int*>::value;
    test = static_assert_same<constant_iterator<BaseIter>::base_type,BaseIter>::value;

    typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;

    test = static_assert_same<IncrementableIter::base_type,BaseIter>::value;
  }

  std::cout << "test successful " << std::endl;
  (void)test;
  return 0;
}
int
main()
{
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
                     dummyT(3), dummyT(4), dummyT(5) };
  const int N = sizeof(array)/sizeof(dummyT);

# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
  boost::shared_ptr<dummyT> zz((dummyT*)0);  // Why? I don't know, but it suppresses a bad instantiation.
# endif
  
  typedef std::vector<boost::shared_ptr<dummyT> > shared_t;
  shared_t shared;
  
  // Concept checks
  {
    typedef boost::indirect_iterator<shared_t::iterator> iter_t;

    BOOST_STATIC_ASSERT(
        has_element_type<
            boost::detail::iterator_traits<shared_t::iterator>::value_type
        >::value
        );
    
    typedef boost::indirect_iterator<
        shared_t::iterator
      , boost::iterator_value<shared_t::iterator>::type const
    > c_iter_t;

# ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
    boost::function_requires< boost_concepts::InteroperableIteratorConcept<iter_t, c_iter_t> >();
# endif 
  }

  // Test indirect_iterator_generator
  {
      for (int jj = 0; jj < N; ++jj)
          shared.push_back(boost::shared_ptr<dummyT>(new dummyT(jj)));
      
      dummyT* ptr[N];
      for (int k = 0; k < N; ++k)
          ptr[k] = array + k;

      typedef boost::indirect_iterator<dummyT**> indirect_iterator;

      typedef boost::indirect_iterator<dummyT**, dummyT const>
          const_indirect_iterator;

      indirect_iterator i(ptr);
      boost::random_access_iterator_test(i, N, array);

      boost::random_access_iterator_test(
          boost::indirect_iterator<shared_t::iterator>(shared.begin())
          , N, array);

      boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
    
      // check operator->
      assert((*i).m_x == i->foo());

      const_indirect_iterator j(ptr);
      boost::random_access_iterator_test(j, N, array);
    
      dummyT const*const* const_ptr = ptr;
      boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
      
      boost::const_nonconst_iterator_test(i, ++j);

      more_indirect_iterator_tests();
  }
  return boost::report_errors();
}
// Test reverse iterator
int main()
{
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
                     dummyT(3), dummyT(4), dummyT(5) };
  const int N = sizeof(array)/sizeof(dummyT);

  // Concept checks
  // Adapting old-style iterators
  {
    typedef boost::reverse_iterator<boost::bidirectional_iterator_archetype<dummyT> > Iter;
    boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
  {
    typedef boost::reverse_iterator<boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
    boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
  // Adapting new-style iterators
  {
    typedef boost::iterator_archetype<
        const dummyT
      , boost::iterator_archetypes::readable_iterator_t
      , boost::bidirectional_traversal_tag
    > iter;
    typedef boost::reverse_iterator<iter> Iter;
    boost::function_requires< boost::InputIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
#if 0
  // It does not seem feasible to make this work. Need to change docs to
  // require at lease Readable for the base iterator. -Jeremy
  {
    typedef boost::iterator_archetype<
        dummyT
      , boost::iterator_archetypes::writable_iterator_t
      , boost::bidirectional_traversal_tag
    > iter;
    typedef boost::reverse_iterator<iter> Iter;
    boost::function_requires< boost_concepts::WritableIteratorConcept<Iter, dummyT> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)  // Causes Internal Error in linker.
  {
    typedef boost::iterator_archetype<
        dummyT
      , boost::iterator_archetypes::readable_writable_iterator_t
      , boost::bidirectional_traversal_tag
    > iter;
    typedef boost::reverse_iterator<iter> Iter;
    boost::function_requires< boost::InputIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
  {
    typedef boost::iterator_archetype<
        const dummyT
      , boost::iterator_archetypes::readable_lvalue_iterator_t
      , boost::bidirectional_traversal_tag
    > iter;
    typedef boost::reverse_iterator<iter> Iter;
    boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
  {
    typedef boost::iterator_archetype<
        dummyT
      , boost::iterator_archetypes::writable_lvalue_iterator_t
      , boost::bidirectional_traversal_tag
    > iter;
    typedef boost::reverse_iterator<iter> Iter;
    boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
    boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  }
#endif
  
  // Test reverse_iterator
  {
    dummyT reversed[N];
    std::copy(array, array + N, reversed);
    std::reverse(reversed, reversed + N);
    
    typedef boost::reverse_iterator<dummyT*> reverse_iterator;
    
    reverse_iterator i(reversed + N);
    boost::random_access_iterator_test(i, N, array);

    boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);

    typedef boost::reverse_iterator<const dummyT*> const_reverse_iterator;
    
    const_reverse_iterator j(reversed + N);
    boost::random_access_iterator_test(j, N, array);

    const dummyT* const_reversed = reversed;
    
    boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
    
    boost::const_nonconst_iterator_test(i, ++j);
  }

  // Test reverse_iterator again, with traits fully deducible on all platforms
  {
    std::deque<dummyT> reversed_container;
    std::reverse_copy(array, array + N, std::back_inserter(reversed_container));
    const std::deque<dummyT>::iterator reversed = reversed_container.begin();


    typedef boost::reverse_iterator<
        std::deque<dummyT>::iterator> reverse_iterator;
    typedef boost::reverse_iterator<
        std::deque<dummyT>::const_iterator> const_reverse_iterator;

    // MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation
    // (e.g. "reversed + N") is used in the constructor below.
    const std::deque<dummyT>::iterator finish = reversed_container.end();
    reverse_iterator i(finish);
    
    boost::random_access_iterator_test(i, N, array);
    boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);

    const_reverse_iterator j = reverse_iterator(finish);
    boost::random_access_iterator_test(j, N, array);

    const std::deque<dummyT>::const_iterator const_reversed = reversed;
    boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
    
    // Many compilers' builtin deque iterators don't interoperate well, though
    // STLport fixes that problem.
#if defined(__SGI_STL_PORT)                                                             \
    || !BOOST_WORKAROUND(__GNUC__, <= 2)                                                \
    && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, <= 1))    \
    && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))                          \
    && !BOOST_WORKAROUND(__LIBCOMO_VERSION__, BOOST_TESTED_AT(29))                      \
    && !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1)
    
    boost::const_nonconst_iterator_test(i, ++j);
    
#endif
  }

  std::cout << "test successful " << std::endl;
  return boost::exit_success;
}
Example #5
0
// Test filter iterator
int main()
{
    // Concept checks
    // Adapting old-style iterators
    {
      typedef boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::InputIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::InputIteratorConcept<Iter> >();
      boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    {
      typedef boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> > Iter;
      boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    // Adapting new-style iterators
    {
      typedef boost::iterator_archetype<
          const dummyT
        , boost::iterator_archetypes::readable_iterator_t
        , boost::single_pass_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::InputIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
    }
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)  // Causes Internal Error in linker.
    {
      typedef boost::iterator_archetype<
          dummyT
        , boost::iterator_archetypes::readable_writable_iterator_t
        , boost::single_pass_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;

      boost::function_requires< boost::InputIteratorConcept<Iter> >();
      boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
    }
#endif 
    {
      typedef boost::iterator_archetype<
          const dummyT
        , boost::iterator_archetypes::readable_iterator_t
        , boost::forward_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::InputIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
    }
    
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)  // Causes Internal Error in linker.
    {
      typedef boost::iterator_archetype<
          dummyT
        , boost::iterator_archetypes::readable_writable_iterator_t
        , boost::forward_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
    }
    {
      typedef boost::iterator_archetype<
          const dummyT
        , boost::iterator_archetypes::readable_lvalue_iterator_t
        , boost::forward_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
    }
    {
      typedef boost::iterator_archetype<
          dummyT
        , boost::iterator_archetypes::writable_lvalue_iterator_t
        , boost::forward_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
    }
#endif 

    {
      typedef boost::iterator_archetype<
          const dummyT
        , boost::iterator_archetypes::readable_iterator_t
        , boost::random_access_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::InputIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)  // Causes Internal Error in linker.
    {
      typedef boost::iterator_archetype<
          dummyT
        , boost::iterator_archetypes::readable_writable_iterator_t
        , boost::random_access_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    {
      typedef boost::iterator_archetype<
          const dummyT
        , boost::iterator_archetypes::readable_lvalue_iterator_t
        , boost::random_access_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
    {
      typedef boost::iterator_archetype<
          dummyT
        , boost::iterator_archetypes::writable_lvalue_iterator_t
        , boost::random_access_traversal_tag
      > BaseIter;
      typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
      boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
      boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
    }
#endif 

    // Run-time tests

    dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
                       dummyT(3), dummyT(4), dummyT(5) };
    const int N = sizeof(array)/sizeof(dummyT);

    typedef boost::filter_iterator<one_or_four, dummyT*> filter_iter;

    boost::bidirectional_readable_iterator_test(
        filter_iter(one_or_four(), array, array+N)
        , dummyT(1), dummyT(4));

    BOOST_STATIC_ASSERT(
        (!boost::is_convertible<
             boost::iterator_traversal<filter_iter>::type
           , boost::random_access_traversal_tag
         >::value
        ));
    
    //# endif
    
    // On compilers not supporting partial specialization, we can do more type
    // deduction with deque iterators than with pointers... unless the library
    // is broken ;-(
    std::deque<dummyT> array2;
    std::copy(array+0, array+N, std::back_inserter(array2));
    boost::bidirectional_readable_iterator_test(
        boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()),
        dummyT(1), dummyT(4));

    boost::bidirectional_readable_iterator_test(
        boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()),
        dummyT(1), dummyT(4));

    boost::bidirectional_readable_iterator_test(
        boost::make_filter_iterator(
              one_or_four()
            , boost::make_reverse_iterator(array2.end())
            , boost::make_reverse_iterator(array2.begin())
            ),
        dummyT(4), dummyT(1));
    
    boost::bidirectional_readable_iterator_test(
        filter_iter(array+0, array+N),
        dummyT(1), dummyT(4));

    boost::bidirectional_readable_iterator_test(
        filter_iter(one_or_four(), array, array + N),
        dummyT(1), dummyT(4));


  std::cout << "test successful " << std::endl;
  return boost::exit_success;
}