mirror of
https://github.com/boostorg/iterator.git
synced 2025-11-03 18:01:37 +01:00
Fix indirect iterators for broken compilers
[SVN r843]
This commit is contained in:
@@ -26,22 +26,64 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
#if defined(BOOST_MSVC_STD_ITERATOR) \
|
||||
|| BOOST_WORKAROUND(_CPPLIB_VER, <= 310) \
|
||||
|| BOOST_WORKAROUND(__GNUC__, <= 2 && !defined(__SGI_STL_PORT))
|
||||
|
||||
// std container random-access iterators don't support mutable/const
|
||||
// interoperability (but may support const/mutable interop).
|
||||
# define NO_MUTABLE_CONST_STD_DEQUE_ITERATOR_INTEROPERABILITY
|
||||
# define NO_MUTABLE_CONST_STD_SET_ITERATOR_INTEROPERABILITY
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC_STD_ITERATOR) \
|
||||
|| defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
// No working iterator_traits implementation, so we must use deque
|
||||
# define RA_CONTAINER std::deque
|
||||
# include <deque>
|
||||
|
||||
# ifdef NO_MUTABLE_CONST_STD_DEQUE_ITERATOR_INTEROPERABILITY
|
||||
# define NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
# define RA_CONTAINER std::vector
|
||||
# include <vector>
|
||||
|
||||
#endif
|
||||
|
||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||
|
||||
using boost::dummyT;
|
||||
|
||||
typedef std::deque<int> storage;
|
||||
typedef std::deque<int*> pointer_deque;
|
||||
typedef RA_CONTAINER<int> storage;
|
||||
typedef RA_CONTAINER<int*> pointer_ra_container;
|
||||
typedef std::set<storage::iterator> iterator_set;
|
||||
|
||||
// Something has to be done about putting this in the lib
|
||||
template <class Iter>
|
||||
struct indirect_const_iterator_traits
|
||||
: boost::detail::indirect_defaults<Iter>
|
||||
{
|
||||
typedef boost::detail::indirect_defaults<Iter> base;
|
||||
typedef typename base::value_type const& reference;
|
||||
typedef typename base::value_type const* pointer;
|
||||
};
|
||||
|
||||
template <class Container>
|
||||
struct indirect_iterator_pair_generator
|
||||
{
|
||||
typedef boost::indirect_iterator<typename Container::iterator> iterator;
|
||||
typedef boost::indirect_iterator<typename Container::const_iterator> const_iterator;
|
||||
|
||||
typedef boost::indirect_iterator<
|
||||
typename Container::iterator
|
||||
, indirect_const_iterator_traits<typename Container::iterator>
|
||||
> const_iterator;
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
@@ -70,40 +112,37 @@ void more_indirect_iterator_tests()
|
||||
storage store(1000);
|
||||
std::generate(store.begin(), store.end(), rand);
|
||||
|
||||
pointer_deque ptr_deque;
|
||||
pointer_ra_container ptr_ra_container;
|
||||
iterator_set iter_set;
|
||||
|
||||
for (storage::iterator p = store.begin(); p != store.end(); ++p)
|
||||
{
|
||||
ptr_deque.push_back(&*p);
|
||||
ptr_ra_container.push_back(&*p);
|
||||
iter_set.insert(p);
|
||||
}
|
||||
|
||||
typedef indirect_iterator_pair_generator<pointer_deque> IndirectDeque;
|
||||
typedef indirect_iterator_pair_generator<pointer_ra_container> indirect_ra_container;
|
||||
|
||||
IndirectDeque::iterator db(ptr_deque.begin());
|
||||
IndirectDeque::iterator de(ptr_deque.end());
|
||||
indirect_ra_container::iterator db(ptr_ra_container.begin());
|
||||
indirect_ra_container::iterator de(ptr_ra_container.end());
|
||||
assert(static_cast<std::size_t>(de - db) == store.size());
|
||||
assert(db + store.size() == de);
|
||||
IndirectDeque::const_iterator dci(db);
|
||||
indirect_ra_container::const_iterator dci = db;
|
||||
|
||||
assert(dci == db);
|
||||
|
||||
// Older Dinkumware and GCC standard lib don't supply symmetric constant/mutable
|
||||
// iterator operators
|
||||
#if !defined(BOOST_MSVC_STD_ITERATOR) \
|
||||
&& !BOOST_WORKAROUND(_CPPLIB_VER, <= 310) \
|
||||
&& !BOOST_WORKAROUND(__GNUC__, <= 2 && !defined(__SGI_STL_PORT))
|
||||
|
||||
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||
assert(db == dci);
|
||||
#endif
|
||||
|
||||
assert(dci != de);
|
||||
assert(dci < de);
|
||||
assert(dci <= de);
|
||||
#endif
|
||||
|
||||
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||
assert(de >= dci);
|
||||
assert(de > dci);
|
||||
#endif
|
||||
|
||||
dci = de;
|
||||
assert(dci == de);
|
||||
@@ -121,6 +160,11 @@ void more_indirect_iterator_tests()
|
||||
indirect_set_iterator se(iter_set.end());
|
||||
const_indirect_set_iterator sci(iter_set.begin());
|
||||
assert(sci == sb);
|
||||
|
||||
# ifndef NO_MUTABLE_CONST_STD_SET_ITERATOR_INTEROPERABILITY
|
||||
assert(se != sci);
|
||||
# endif
|
||||
|
||||
assert(sci != se);
|
||||
sci = se;
|
||||
assert(sci == se);
|
||||
@@ -140,7 +184,7 @@ main()
|
||||
dummyT(3), dummyT(4), dummyT(5) };
|
||||
const int N = sizeof(array)/sizeof(dummyT);
|
||||
|
||||
typedef std::deque<boost::shared_ptr<dummyT> > shared_t;
|
||||
typedef RA_CONTAINER<boost::shared_ptr<dummyT> > shared_t;
|
||||
shared_t shared;
|
||||
|
||||
// Concept checks
|
||||
@@ -148,12 +192,9 @@ main()
|
||||
typedef boost::indirect_iterator<shared_t::iterator> iter_t;
|
||||
typedef boost::indirect_iterator<shared_t::const_iterator> c_iter_t;
|
||||
|
||||
// Older Dinkumware and GCC standard lib don't supply symmetric constant/mutable
|
||||
// iterator operators
|
||||
#if !defined(BOOST_MSVC_STD_ITERATOR) && (!defined(_CPPLIB_VER) || _CPPLIB_VER > 310) \
|
||||
&& (__GNUC__ != 2 || defined(__SGI_STL_PORT))
|
||||
# ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||
boost::function_requires< boost_concepts::InteroperableConcept<iter_t, c_iter_t> >();
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
// Test indirect_iterator_generator
|
||||
@@ -167,22 +208,15 @@ main()
|
||||
|
||||
typedef boost::indirect_iterator<dummyT**> indirect_iterator;
|
||||
|
||||
typedef boost::indirect_iterator<dummyT const* const*> const_indirect_iterator;
|
||||
typedef boost::indirect_iterator<dummyT**, indirect_const_iterator_traits<dummyT**> >
|
||||
const_indirect_iterator;
|
||||
|
||||
indirect_iterator i(ptr);
|
||||
boost::random_access_iterator_test(i, N, array);
|
||||
|
||||
#if __GNUC__ != 2
|
||||
// We're having trouble auto-detecting smart pointers with
|
||||
// gcc-2.95 via the nested element_type member. However, we
|
||||
// really ought to have a specializable is_pointer template
|
||||
// which can be used instead with something like
|
||||
// boost/python/pointee.hpp to find the value_type.
|
||||
|
||||
boost::random_access_iterator_test(
|
||||
boost::indirect_iterator<shared_t::iterator>(shared.begin())
|
||||
, N, array);
|
||||
#endif
|
||||
|
||||
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user