mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-28 11:57:33 +02:00
merged from trunk
[SVN r21516]
This commit is contained in:
@ -21,7 +21,13 @@ namespace boost { namespace detail {
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
template <bool GreaterEqual, bool LessEqual>
|
template <bool GreaterEqual, bool LessEqual>
|
||||||
struct minimum_category_impl;
|
struct minimum_category_impl
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
;
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
struct error_not_related_by_convertibility;
|
struct error_not_related_by_convertibility;
|
||||||
@ -58,15 +64,9 @@ template <>
|
|||||||
struct minimum_category_impl<false,false>
|
struct minimum_category_impl<false,false>
|
||||||
{
|
{
|
||||||
template <class T1, class T2> struct apply
|
template <class T1, class T2> struct apply
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
|
||||||
{
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
# else
|
|
||||||
: error_not_related_by_convertibility<T1,T2>
|
: error_not_related_by_convertibility<T1,T2>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
# endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
||||||
|
@ -12,11 +12,15 @@
|
|||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
#include <boost/pointee.hpp>
|
||||||
|
#include <boost/indirect_reference.hpp>
|
||||||
#include <boost/type_traits/remove_cv.hpp>
|
#include <boost/detail/iterator.hpp>
|
||||||
|
|
||||||
#include <boost/python/detail/indirect_traits.hpp>
|
#include <boost/python/detail/indirect_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/add_reference.hpp>
|
||||||
|
|
||||||
#include <boost/mpl/bool.hpp>
|
#include <boost/mpl/bool.hpp>
|
||||||
#include <boost/mpl/identity.hpp>
|
#include <boost/mpl/identity.hpp>
|
||||||
#include <boost/mpl/apply_if.hpp>
|
#include <boost/mpl/apply_if.hpp>
|
||||||
@ -37,116 +41,8 @@ namespace boost
|
|||||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||||
class indirect_iterator;
|
class indirect_iterator;
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct referent;
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
struct unspecified {};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Detection for whether a type has a nested `element_type'
|
|
||||||
// typedef. Used to detect smart pointers. For compilers not
|
|
||||||
// supporting mpl's has_xxx, we supply specializations. 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.
|
|
||||||
//
|
|
||||||
# ifndef BOOST_MPL_NO_AUX_HAS_XXX
|
|
||||||
namespace aux
|
|
||||||
{
|
|
||||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct has_element_type
|
|
||||||
: mpl::bool_<
|
|
||||||
mpl::if_<
|
|
||||||
is_class<T>
|
|
||||||
, ::boost::detail::aux::has_element_type<T>
|
|
||||||
, mpl::false_
|
|
||||||
>::type::value
|
|
||||||
>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
# else
|
|
||||||
template <class T>
|
|
||||||
struct has_element_type
|
|
||||||
: mpl::false_ {};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct has_element_type<boost::shared_ptr<T> >
|
|
||||||
: mpl::true_ {};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct has_element_type<boost::scoped_ptr<T> >
|
|
||||||
: mpl::true_ {};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct has_element_type<std::auto_ptr<T> >
|
|
||||||
: mpl::true_ {};
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Metafunction accessing the nested ::element_type
|
|
||||||
template <class T>
|
|
||||||
struct element_type
|
|
||||||
: mpl::identity<typename T::element_type>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct iterator_is_mutable
|
|
||||||
: mpl::not_<
|
|
||||||
boost::python::detail::is_reference_to_const<
|
|
||||||
typename iterator_reference<T>::type
|
|
||||||
>
|
|
||||||
>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct not_int_impl
|
|
||||||
{
|
|
||||||
template <class U>
|
|
||||||
struct apply {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct not_int_impl<int> {};
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
struct not_int
|
|
||||||
: not_int_impl<T>::template apply<U> {};
|
|
||||||
|
|
||||||
|
|
||||||
template <class Dereferenceable>
|
|
||||||
struct class_has_element_type
|
|
||||||
: mpl::and_<
|
|
||||||
is_class<Dereferenceable>
|
|
||||||
, has_element_type<Dereferenceable>
|
|
||||||
>
|
|
||||||
{};
|
|
||||||
|
|
||||||
// If the Value parameter is unspecified, we use this metafunction
|
|
||||||
// to deduce the default types
|
|
||||||
template <class Dereferenceable>
|
|
||||||
struct default_indirect_value
|
|
||||||
{
|
|
||||||
typedef typename remove_cv<
|
|
||||||
typename referent<Dereferenceable>::type
|
|
||||||
>::type referent_t;
|
|
||||||
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
mpl::or_<
|
|
||||||
class_has_element_type<Dereferenceable>
|
|
||||||
, iterator_is_mutable<Dereferenceable>
|
|
||||||
>
|
|
||||||
, referent_t
|
|
||||||
, referent_t const
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||||
struct indirect_base
|
struct indirect_base
|
||||||
{
|
{
|
||||||
@ -156,10 +52,17 @@ namespace boost
|
|||||||
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
||||||
, Iter
|
, Iter
|
||||||
, typename ia_dflt_help<
|
, typename ia_dflt_help<
|
||||||
Value, default_indirect_value<dereferenceable>
|
Value, pointee<dereferenceable>
|
||||||
>::type
|
>::type
|
||||||
, Category
|
, Category
|
||||||
, Reference
|
, typename ia_dflt_help<
|
||||||
|
Reference
|
||||||
|
, mpl::apply_if<
|
||||||
|
is_same<Value,use_default>
|
||||||
|
, indirect_reference<dereferenceable>
|
||||||
|
, add_reference<Value>
|
||||||
|
>
|
||||||
|
>::type
|
||||||
, Difference
|
, Difference
|
||||||
> type;
|
> type;
|
||||||
};
|
};
|
||||||
@ -168,19 +71,6 @@ namespace boost
|
|||||||
struct indirect_base<int, int, int, int, int> {};
|
struct indirect_base<int, int, int, int, int> {};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// User-specializable metafunction which returns the referent of a
|
|
||||||
// dereferenceable type. The default implementation returns
|
|
||||||
// Dereferenceable::element_type if such a member exists (thus
|
|
||||||
// handling the boost smart pointers and auto_ptr), and
|
|
||||||
// iterator_traits<Dereferenceable>::value_type otherwise.
|
|
||||||
template <class Dereferenceable>
|
|
||||||
struct referent
|
|
||||||
: mpl::apply_if<
|
|
||||||
detail::class_has_element_type<Dereferenceable>
|
|
||||||
, detail::element_type<Dereferenceable>
|
|
||||||
, iterator_value<Dereferenceable>
|
|
||||||
>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Iterator
|
class Iterator
|
||||||
|
@ -346,35 +346,50 @@ namespace detail
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename Iterator, typename ConstIterator>
|
template <typename Iterator, typename ConstIterator>
|
||||||
class InteroperableConcept
|
class InteroperableConcept
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
typedef typename boost::detail::pure_traversal_tag<
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
typename boost::iterator_traversal<
|
||||||
difference_type;
|
Iterator
|
||||||
|
>::type
|
||||||
|
>::type traversal_category;
|
||||||
|
|
||||||
|
typedef typename
|
||||||
|
boost::detail::iterator_traits<Iterator>::difference_type
|
||||||
|
difference_type;
|
||||||
|
|
||||||
typedef typename boost::iterator_traversal<ConstIterator>::type
|
typedef typename boost::detail::pure_traversal_tag<
|
||||||
const_traversal_category;
|
typename boost::iterator_traversal<
|
||||||
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
|
ConstIterator
|
||||||
const_difference_type;
|
>::type
|
||||||
|
>::type const_traversal_category;
|
||||||
|
|
||||||
|
typedef typename
|
||||||
|
boost::detail::iterator_traits<ConstIterator>::difference_type
|
||||||
|
const_difference_type;
|
||||||
|
|
||||||
void constraints() {
|
void constraints()
|
||||||
BOOST_STATIC_ASSERT((boost::is_same< difference_type,
|
{
|
||||||
const_difference_type>::value));
|
BOOST_STATIC_ASSERT(
|
||||||
BOOST_STATIC_ASSERT((boost::is_same< traversal_category,
|
(boost::is_same< difference_type, const_difference_type>::value)
|
||||||
const_traversal_category>::value));
|
);
|
||||||
|
|
||||||
// ToDo check what the std really requires
|
BOOST_STATIC_ASSERT(
|
||||||
|
(boost::is_same< traversal_category, const_traversal_category>::value)
|
||||||
// detail::Operations<traversal_category>::constraints(i, ci);
|
);
|
||||||
|
|
||||||
ci = i;
|
// ToDo check what the std really requires
|
||||||
|
|
||||||
}
|
// detail::Operations<traversal_category>::constraints(i, ci);
|
||||||
Iterator i;
|
|
||||||
ConstIterator ci;
|
ci = i;
|
||||||
};
|
|
||||||
|
}
|
||||||
|
Iterator i;
|
||||||
|
ConstIterator ci;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace boost_concepts
|
} // namespace boost_concepts
|
||||||
|
|
||||||
|
@ -18,7 +18,13 @@ test-suite iterator
|
|||||||
# compilation problems.
|
# compilation problems.
|
||||||
[ run is_convertible_fail.cpp ]
|
[ run is_convertible_fail.cpp ]
|
||||||
|
|
||||||
[ run zip_iterator_test.cpp ]
|
[ run zip_iterator_test.cpp
|
||||||
|
: : :
|
||||||
|
|
||||||
|
# stlport's debug mode generates long symbols which overwhelm
|
||||||
|
# vc6
|
||||||
|
<msvc-stlport><*><runtime-build>release
|
||||||
|
]
|
||||||
|
|
||||||
# These tests should work for just about everything.
|
# These tests should work for just about everything.
|
||||||
[ compile is_lvalue_iterator.cpp ]
|
[ compile is_lvalue_iterator.cpp ]
|
||||||
@ -31,6 +37,7 @@ test-suite iterator
|
|||||||
[ compile iterator_archetype_cc.cpp ]
|
[ compile iterator_archetype_cc.cpp ]
|
||||||
[ run transform_iterator_test.cpp ]
|
[ run transform_iterator_test.cpp ]
|
||||||
[ run indirect_iterator_test.cpp ]
|
[ run indirect_iterator_test.cpp ]
|
||||||
|
[ compile indirect_iterator_member_types.cpp ]
|
||||||
[ run filter_iterator_test.cpp ]
|
[ run filter_iterator_test.cpp ]
|
||||||
[ run reverse_iterator_test.cpp ]
|
[ run reverse_iterator_test.cpp ]
|
||||||
[ run counting_iterator_test.cpp ]
|
[ run counting_iterator_test.cpp ]
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
|
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||||
|
|
||||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -43,6 +45,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> struct see_type;
|
||||||
|
template <int I> struct see_val;
|
||||||
|
|
||||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||||
|
|
||||||
using boost::dummyT;
|
using boost::dummyT;
|
||||||
@ -136,6 +141,10 @@ void more_indirect_iterator_tests()
|
|||||||
assert(std::equal(db, de, store.begin()));
|
assert(std::equal(db, de, store.begin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// element_type detector; defaults to true so the test passes when
|
||||||
|
// has_xxx isn't implemented
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_element_type, element_type, true)
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
@ -143,6 +152,10 @@ main()
|
|||||||
dummyT(3), dummyT(4), dummyT(5) };
|
dummyT(3), dummyT(4), dummyT(5) };
|
||||||
const int N = sizeof(array)/sizeof(dummyT);
|
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;
|
typedef std::vector<boost::shared_ptr<dummyT> > shared_t;
|
||||||
shared_t shared;
|
shared_t shared;
|
||||||
|
|
||||||
@ -151,9 +164,8 @@ main()
|
|||||||
typedef boost::indirect_iterator<shared_t::iterator> iter_t;
|
typedef boost::indirect_iterator<shared_t::iterator> iter_t;
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
boost::detail::has_element_type<
|
has_element_type<
|
||||||
boost::shared_ptr<dummyT>
|
boost::detail::iterator_traits<shared_t::iterator>::value_type
|
||||||
// std::iterator_traits<shared_t::iterator>::value_type
|
|
||||||
>::value
|
>::value
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -195,7 +207,6 @@ main()
|
|||||||
|
|
||||||
const_indirect_iterator j(ptr);
|
const_indirect_iterator j(ptr);
|
||||||
boost::random_access_iterator_test(j, N, array);
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
|
||||||
|
|
||||||
dummyT const*const* const_ptr = ptr;
|
dummyT const*const* const_ptr = ptr;
|
||||||
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
|
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
# define STATIC_ASSERT_SAME_DWA2003530_HPP
|
# define STATIC_ASSERT_SAME_DWA2003530_HPP
|
||||||
|
|
||||||
# include <boost/type.hpp>
|
# include <boost/type.hpp>
|
||||||
|
# include <boost/static_assert.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
@ -32,4 +33,8 @@ struct static_assert_same
|
|||||||
{};
|
{};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define STATIC_ASSERT_SAME( T1,T2 ) \
|
||||||
|
enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \
|
||||||
|
= static_assert_same<T1,T2>::value }
|
||||||
|
|
||||||
#endif // STATIC_ASSERT_SAME_DWA2003530_HPP
|
#endif // STATIC_ASSERT_SAME_DWA2003530_HPP
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <functional>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
#include <boost/iterator/is_readable_iterator.hpp>
|
#include <boost/iterator/is_readable_iterator.hpp>
|
||||||
|
Reference in New Issue
Block a user