Compare commits

..

30 Commits

Author SHA1 Message Date
Dave Abrahams
6ca935d9fe Allow WritableIteratorConcept to be used with one parameter for
iterators with a sensible value_type


[SVN r20904]
2003-11-21 23:39:10 +00:00
Dave Abrahams
dea89aa823 Added missing #include
[SVN r20896]
2003-11-20 21:42:38 +00:00
Dave Abrahams
ce5d2ec4b4 Reformatting
[SVN r20895]
2003-11-20 21:42:14 +00:00
Dave Abrahams
640379ac34 Better error messages on failure
[SVN r20894]
2003-11-20 21:41:33 +00:00
Dave Abrahams
7cbe926f29 BOOST_TT_BROKEN_COMPILER_SPEC(dummyT) is now supplied with dummyT
[SVN r20893]
2003-11-20 21:41:13 +00:00
Dave Abrahams
5113e4fbec Broken compiler workarounds
[SVN r20892]
2003-11-20 21:40:50 +00:00
Dave Abrahams
66183e43f5 Broaden tests to detect more cases.
[SVN r20891]
2003-11-20 21:40:16 +00:00
Dave Abrahams
4247559960 Broken compiler workarounds, cleanup
[SVN r20890]
2003-11-20 21:38:48 +00:00
Dave Abrahams
c7c6448bd5 Make zip_iterator's test run later, because it's failing on a few
compilers still.


[SVN r20889]
2003-11-20 21:38:09 +00:00
Dave Abrahams
218778bb94 Workarounds for broken compilers
[SVN r20886]
2003-11-20 21:17:54 +00:00
Dave Abrahams
4b4de44736 Workarounds for vc6 and vc7
[SVN r20885]
2003-11-20 21:17:00 +00:00
Dave Abrahams
8deb1c20fb Don't adjust default reference type computation based on
BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY


[SVN r20884]
2003-11-20 21:15:31 +00:00
Dave Abrahams
20e6d71755 undo pointless Borland workarounds
[SVN r20883]
2003-11-20 21:14:29 +00:00
Dave Abrahams
52f72c2115 Uncomment mistakenly disabled tests
[SVN r20880]
2003-11-20 16:17:55 +00:00
Dave Abrahams
6b2da49430 Borland workarounds
[SVN r20879]
2003-11-20 16:17:30 +00:00
Dave Abrahams
f46f7f8091 vc6 workarounds
[SVN r20869]
2003-11-19 22:04:02 +00:00
Dave Abrahams
22670777b8 Change the way input_output_iterator_tag is convertible to
output_iterator_tag from inheritance to implicit conversion operator,
to avoid some tag dispatch ambiguities.


[SVN r20868]
2003-11-19 22:03:48 +00:00
Dave Abrahams
6270de1db0 ETI workaround
[SVN r20867]
2003-11-19 22:02:36 +00:00
Dave Abrahams
6e06e4f89e Refactored minimum_category
[SVN r20865]
2003-11-19 20:16:52 +00:00
Dave Abrahams
eb73b8e0e2 Got everything working with GCC
[SVN r20864]
2003-11-19 20:08:00 +00:00
Dave Abrahams
7ffe2601a9 Commenting and cleanups after a hurried checkin last night
[SVN r20858]
2003-11-19 14:26:43 +00:00
Dave Abrahams
62b70f57a9 progress
[SVN r20853]
2003-11-19 04:25:17 +00:00
Dave Abrahams
cd37eb3bfb Modified Files:
Tag: simplify
	iterator_adaptor.hpp iterator_categories.hpp
	iterator_facade.hpp
 Added Files:
  Tag: simplify
 	is_lvalue_iterator.hpp is_readable_iterator.hpp
 	detail/any_conversion_eater.hpp

The above files were moved over from HEAD and will cause confusion during the merge

Got iterator_adaptor_test.cpp working


[SVN r20843]
2003-11-18 04:19:28 +00:00
Dave Abrahams
bda5890235 iterator_adaptor_test
[SVN r20842]
2003-11-18 04:08:40 +00:00
nobody
d51c5ebf07 This commit was manufactured by cvs2svn to create branch 'simplify'.
[SVN r20841]
2003-11-18 03:04:16 +00:00
Dave Abrahams
6f90b8b161 iterator_categories reformed, test added
[SVN r20829]
2003-11-17 16:52:15 +00:00
Dave Abrahams
6ec791e3b9 checkpoint
[SVN r20733]
2003-11-08 04:12:18 +00:00
Dave Abrahams
20f188d971 progress
[SVN r20167]
2003-09-23 22:58:59 +00:00
Dave Abrahams
7273be17c0 Begun simplification
[SVN r20165]
2003-09-23 02:04:53 +00:00
nobody
77a89a0b89 This commit was manufactured by cvs2svn to create branch 'simplify'.
[SVN r20118]
2003-09-19 18:44:54 +00:00
49 changed files with 3550 additions and 1559 deletions

View File

@@ -1,56 +0,0 @@
// (C) Copyright Jeremy Siek 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History:
// 27 Feb 2001 Jeremy Siek
// Initial checkin.
#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
#include <iterator>
namespace boost {
template <class UnaryFunction>
class function_output_iterator {
typedef function_output_iterator self;
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator() {}
explicit function_output_iterator(const UnaryFunction& f)
: m_f(f) {}
struct output_proxy {
output_proxy(UnaryFunction& f) : m_f(f) { }
template <class T> output_proxy& operator=(const T& value) {
m_f(value);
return *this;
}
UnaryFunction& m_f;
};
output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; }
self& operator++(int) { return *this; }
private:
UnaryFunction m_f;
};
template <class UnaryFunction>
inline function_output_iterator<UnaryFunction>
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
return function_output_iterator<UnaryFunction>(f);
}
} // namespace boost
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP

View File

@@ -1,59 +0,0 @@
// interator.hpp workarounds for non-conforming standard libraries ---------//
// (C) Copyright Beman Dawes 2000. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams)
// 26 Jun 00 Initial version (Jeremy Siek)
#ifndef BOOST_ITERATOR_HPP
#define BOOST_ITERATOR_HPP
#include <iterator>
#include <cstddef> // std::ptrdiff_t
#include <boost/config.hpp>
namespace boost
{
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
template <class Category, class T,
class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator
{
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
# else
// declare iterator_base in namespace detail to work around MSVC bugs which
// prevent derivation from an identically-named class in a different namespace.
namespace detail {
template <class Category, class T, class Distance, class Pointer, class Reference>
# if !defined(BOOST_MSVC_STD_ITERATOR)
struct iterator_base : std::iterator<Category, T, Distance, Pointer, Reference> {};
# else
struct iterator_base : std::iterator<Category, T, Distance>
{
typedef Reference reference;
typedef Pointer pointer;
typedef Distance difference_type;
};
# endif
}
template <class Category, class T, class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator : boost::detail::iterator_base<Category, T, Distance, Pointer, Reference> {};
# endif
} // namespace boost
#endif // BOOST_ITERATOR_HPP

View File

@@ -1,7 +1,8 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COUNTING_ITERATOR_DWA200348_HPP
# define COUNTING_ITERATOR_DWA200348_HPP
@@ -10,7 +11,7 @@
# include <boost/mpl/bool.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/apply_if.hpp>
namespace boost {
@@ -33,11 +34,20 @@ namespace detail
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
# if defined(BOOST_HAS_LONG_LONG)
BOOST_STATIC_CONSTANT(
bool, value = (
std::numeric_limits<T>::is_specialized
| boost::is_same<T,long long>::value
| boost::is_same<T,unsigned long long>::value
));
# else
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
# endif
# else
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
# if !defined(__BORLANDC__)
BOOST_STATIC_CONSTANT(
bool, value = (
boost::is_convertible<int,T>::value
@@ -54,21 +64,6 @@ namespace detail
struct is_numeric
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
{};
# if defined(BOOST_HAS_LONG_LONG)
template <>
struct is_numeric< ::boost::long_long_type>
: mpl::true_ {};
template <>
struct is_numeric< ::boost::ulong_long_type>
: mpl::true_ {};
# endif
// Some compilers fail to have a numeric_limits specialization
template <>
struct is_numeric<wchar_t>
: mpl::true_ {};
template <class T>
struct numeric_difference
@@ -83,7 +78,7 @@ namespace detail
{
typedef typename detail::ia_dflt_help<
CategoryOrTraversal
, mpl::eval_if<
, mpl::apply_if<
is_numeric<Incrementable>
, mpl::identity<random_access_traversal_tag>
, iterator_traversal<Incrementable>
@@ -92,7 +87,7 @@ namespace detail
typedef typename detail::ia_dflt_help<
Difference
, mpl::eval_if<
, mpl::apply_if<
is_numeric<Incrementable>
, numeric_difference<Incrementable>
, iterator_difference<Incrementable>
@@ -126,7 +121,7 @@ namespace detail
{
static Difference distance(Incrementable1 x, Incrementable2 y)
{
return y - x;
return boost::detail::distance(x, y);
}
};

View File

@@ -0,0 +1 @@
#error obsolete

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// no include guard multiple inclusion intended
@@ -22,11 +24,7 @@
# define BOOST_ITERATOR_CONFIG_DEF
#endif
// We enable this always now. Otherwise, the simple case in
// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
// because the operator-> return is improperly deduced as a non-const
// pointer.
#if 1 || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
// Recall that in general, compilers without partial specialization
@@ -40,7 +38,7 @@
// end up using a proxy for operator[] when we otherwise shouldn't.
// Using reference constness gives it an extra hint that it can
// return the value_type from operator[] directly, but is not
// strictly necessary. Not sure how best to resolve this one.
// strictly neccessary. Not sure how best to resolve this one.
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
@@ -48,8 +46,7 @@
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))
# define BOOST_NO_LVALUE_RETURN_DETECTION
# if 0 // test code
@@ -82,17 +79,55 @@
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \
|| BOOST_WORKAROUND(__MWERKS__, <= 0x3000) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
# define BOOST_NO_SFINAE // "Substitution Failure Is Not An Error not implemented"
# if 0 // test code
template <bool x>
struct bar
{
typedef int type;
};
template <>
struct bar<false>
{
};
template <class T>
struct foo : bar<(sizeof(T) == 1)>
{
};
template <class T>
char* f(int, typename foo<T>::type = 0) { return 0; }
template <class T>
int f(...) { return 0; }
char* x = f<char>(0);
int y = f<char[2]>(0);
int main()
{
return 0;
}
# endif
#endif
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
#endif
#if BOOST_WORKAROUND(__GNUC__, == 2) \
|| BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
#if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(3)) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
# if 0 // test code
#include <boost/type_traits/is_convertible.hpp>
template <class T>
struct foo
{
@@ -115,7 +150,7 @@
# define BOOST_ITERATOR_NO_MPL_AUX_HAS_XXX // "MPL's has_xxx facility doesn't work"
#endif
#if !defined(BOOST_MSVC) && (defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE))
#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE)
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#endif
@@ -125,16 +160,4 @@
# define BOOST_ARG_DEPENDENT_TYPENAME
# endif
# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// GCC-2.95 eagerly instantiates templated constructors and conversion
// operators in convertibility checks, causing premature errors.
//
// Borland's problems are harder to diagnose due to lack of an
// instantiation stack backtrace. They may be due in part to the fact
// that it drops cv-qualification willy-nilly in templates.
# define BOOST_NO_ONE_WAY_ITERATOR_INTEROP
# endif
// no include guard; multiple inclusion intended
// no include guard multiple inclusion intended

View File

@@ -1,7 +1,9 @@
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// no include guard multiple inclusion intended
@@ -11,12 +13,12 @@
// 23/02/03 thw
//
#undef BOOST_NO_SFINAE
#undef BOOST_NO_IS_CONVERTIBLE
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#undef BOOST_ARG_DEPENDENT_TYPENAME
#undef BOOST_NO_LVALUE_RETURN_DETECTION
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
#ifdef BOOST_ITERATOR_CONFIG_DEF
# undef BOOST_ITERATOR_CONFIG_DEF

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ENABLE_IF_23022003THW_HPP
#define BOOST_ENABLE_IF_23022003THW_HPP
@@ -72,7 +74,7 @@ namespace boost
: mpl::identity<Return>
# endif
{
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
typedef Return type;
# endif
};

View File

@@ -11,7 +11,7 @@
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
# include <boost/mpl/and.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/is_same.hpp>
@@ -24,7 +24,7 @@
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/detail/indirect_traits.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# endif
//
@@ -61,7 +61,7 @@ struct iterator_writability_disabled
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
: mpl::or_<
is_const<Reference>
, boost::detail::indirect_traits::is_reference_to_const<Reference>
, python::detail::is_reference_to_const<Reference>
, is_const<ValueParam>
>
# else
@@ -86,12 +86,12 @@ struct iterator_writability_disabled
//
template <class Traversal, class ValueParam, class Reference>
struct iterator_facade_default_category
: mpl::eval_if<
: mpl::apply_if<
mpl::and_<
is_reference<Reference>
, is_convertible<Traversal,forward_traversal_tag>
>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<std::random_access_iterator_tag>
, mpl::if_<
@@ -100,15 +100,22 @@ struct iterator_facade_default_category
, std::forward_iterator_tag
>
>
, typename mpl::eval_if<
, typename mpl::apply_if<
mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag>
// check for readability
, is_convertible<Reference, ValueParam>
, mpl::or_< // check for readability
is_same<ValueParam,use_default>
, is_convertible<Reference, ValueParam>
>
>
, mpl::identity<std::input_iterator_tag>
, mpl::identity<Traversal>
, mpl::if_<
iterator_writability_disabled<ValueParam,Reference>
, std::input_iterator_tag
, input_output_iterator_tag
>
, mpl::identity<std::output_iterator_tag>
>
>
{
@@ -160,9 +167,7 @@ struct iterator_category_with_traversal
BOOST_STATIC_ASSERT(is_iterator_category<Category>::value);
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
BOOST_STATIC_ASSERT(!is_iterator_traversal<Category>::value);
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
BOOST_STATIC_ASSERT(is_iterator_traversal<Traversal>::value);
# endif
# endif
};
@@ -194,7 +199,7 @@ struct facade_iterator_category_impl
//
template <class CategoryOrTraversal, class ValueParam, class Reference>
struct facade_iterator_category
: mpl::eval_if<
: mpl::apply_if<
is_iterator_category<CategoryOrTraversal>
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>

View File

@@ -21,17 +21,7 @@ namespace boost { namespace detail {
//
//
template <bool GreaterEqual, bool LessEqual>
struct minimum_category_impl
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
{
template <class T1, class T2> struct apply
{
typedef T2 type;
};
typedef void type;
}
# endif
;
struct minimum_category_impl;
template <class T1, class T2>
struct error_not_related_by_convertibility;
@@ -77,16 +67,10 @@ template <class T1 = mpl::_1, class T2 = mpl::_2>
struct minimum_category
{
typedef minimum_category_impl<
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
is_same<T2,int>::value ||
# endif
::boost::is_convertible<T1,T2>::value
, ::boost::is_convertible<T2,T1>::value
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|| is_same<T1,int>::value
# endif
> outer;
typedef typename outer::template apply<T1,T2> inner;
typedef typename inner::type type;
@@ -99,18 +83,16 @@ struct minimum_category<mpl::_1,mpl::_2>
template <class T1, class T2>
struct apply : minimum_category<T1,T2>
{};
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct minimum_category<int,int>
{
typedef int type;
};
# endif
}} // namespace boost::detail
#endif // MINIMUM_CATEGORY_DWA20031119_HPP

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
@@ -31,9 +33,9 @@ namespace boost
, typename mpl::if_<
is_convertible<
typename iterator_traversal<Iterator>::type
, random_access_traversal_tag
, bidirectional_traversal_tag
>
, bidirectional_traversal_tag
, forward_traversal_tag
, use_default
>::type
> type;
@@ -122,7 +124,7 @@ namespace boost
, Iterator
>::type x
, Iterator end = Iterator()
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
, Predicate* = 0
#endif
)

View File

@@ -1,31 +1,29 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/pointee.hpp>
#include <boost/indirect_reference.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/detail/indirect_traits.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/python/detail/indirect_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/aux_/has_xxx.hpp>
#ifdef BOOST_MPL_CFG_NO_HAS_XXX
#ifdef BOOST_MPL_NO_AUX_HAS_XXX
# include <boost/shared_ptr.hpp>
# include <boost/scoped_ptr.hpp>
# include <boost/mpl/bool.hpp>
@@ -39,8 +37,116 @@ namespace boost
template <class Iter, class Value, class Category, class Reference, class Difference>
class indirect_iterator;
template <class T>
struct referent;
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>
struct indirect_base
{
@@ -50,17 +156,10 @@ namespace boost
indirect_iterator<Iter, Value, Category, Reference, Difference>
, Iter
, typename ia_dflt_help<
Value, pointee<dereferenceable>
Value, default_indirect_value<dereferenceable>
>::type
, Category
, typename ia_dflt_help<
Reference
, mpl::eval_if<
is_same<Value,use_default>
, indirect_reference<dereferenceable>
, add_reference<Value>
>
>::type
, Reference
, Difference
> type;
};
@@ -69,6 +168,19 @@ namespace boost
struct indirect_base<int, int, int, int, int> {};
} // 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 <
class Iterator

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_INTEROPERABLE_23022003THW_HPP
# define BOOST_INTEROPERABLE_23022003THW_HPP

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
@@ -19,6 +21,8 @@
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#include <boost/python/detail/is_xxx.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
@@ -100,22 +104,7 @@ namespace boost
// false positives for user/library defined iterator types. See comments
// on operator implementation for consequences.
//
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template<typename From, typename To>
struct enable_if_convertible
{
typedef typename mpl::if_<
mpl::or_<
is_same<From,To>
, is_convertible<From, To>
>
, detail::enable_type
, int&
>::type type;
};
# elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
template <class From, class To>
struct enable_if_convertible
@@ -159,7 +148,7 @@ namespace boost
// DefaultNullaryFn, otherwise return T.
template <class T, class DefaultNullaryFn>
struct ia_dflt_help
: mpl::eval_if<
: mpl::apply_if<
is_same<T, use_default>
, DefaultNullaryFn
, mpl::identity<T>
@@ -185,7 +174,7 @@ namespace boost
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename detail::ia_dflt_help<
Value
, mpl::eval_if<
, mpl::apply_if<
is_same<Reference,use_default>
, iterator_value<Base>
, remove_reference<Reference>
@@ -204,7 +193,7 @@ namespace boost
, typename detail::ia_dflt_help<
Reference
, mpl::eval_if<
, mpl::apply_if<
is_same<Value,use_default>
, iterator_reference<Base>
, add_reference<Value>
@@ -217,13 +206,7 @@ namespace boost
>
type;
};
// workaround for aC++ CR JAGaf33512
template <class Tr1, class Tr2>
inline void iterator_adaptor_assert_traversal ()
{
BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
}
template <class T> int static_assert_convertible_to(T);
}
//
@@ -266,27 +249,22 @@ namespace boost
{
friend class iterator_core_access;
protected:
typedef typename detail::iterator_adaptor_base<
Derived, Base, Value, Traversal, Reference, Difference
>::type super_t;
public:
iterator_adaptor() {}
explicit iterator_adaptor(Base const &iter)
explicit iterator_adaptor(Base iter)
: m_iterator(iter)
{
}
typedef Base base_type;
Base const& base() const
Base base() const
{ return m_iterator; }
protected:
// for convenience in derived classes
typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
//
// lvalue access to the Base object for Derived
//
@@ -323,7 +301,8 @@ namespace boost
>::type my_traversal;
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
typedef int assertion[sizeof(detail::static_assert_convertible_to<cat>(my_traversal()))];
// BOOST_STATIC_ASSERT((is_convertible<my_traversal,cat>::value));
void advance(typename super_t::difference_type n)
{

View File

@@ -1,7 +1,8 @@
// (C) Copyright Jeremy Siek 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ITERATOR_ARCHETYPES_HPP
#define BOOST_ITERATOR_ARCHETYPES_HPP
@@ -18,14 +19,12 @@
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>
#include <boost/mpl/bitand.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/identity.hpp>
@@ -81,26 +80,26 @@ namespace detail
template <class T>
struct assign_proxy
{
assign_proxy& operator=(T) { return *this; }
assign_proxy& operator=(T);
};
template <class T>
struct read_proxy
{
operator T() { return static_object<T>::get(); }
operator T();
};
template <class T>
struct read_write_proxy
: read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
: assign_proxy<T>
, read_proxy<T>
{
read_write_proxy& operator=(T) { return *this; }
};
template <class T>
struct arrow_proxy
{
T const* operator->() const { return 0; }
T const* operator->() const;
};
struct no_operator_brackets {};
@@ -108,21 +107,21 @@ namespace detail
template <class ValueType>
struct readable_operator_brackets
{
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
read_proxy<ValueType> operator[](std::ptrdiff_t n) const;
};
template <class ValueType>
struct writable_operator_brackets
{
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const;
};
template <class Value, class AccessCategory, class TraversalCategory>
struct operator_brackets
: mpl::aux::msvc_eti_base<
typename mpl::eval_if<
typename mpl::apply_if<
is_convertible<TraversalCategory, random_access_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
iterator_archetypes::has_access<
AccessCategory
, iterator_archetypes::writable_iterator_t
@@ -148,26 +147,12 @@ namespace detail
template <class Derived,class Value> struct archetype;
};
// Constructor argument for those iterators that
// are not default constructible
struct ctor_arg {};
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_
: mpl::aux::msvc_eti_base<
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
>::type
{
typedef typename
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
base;
traversal_archetype_() {}
traversal_archetype_(ctor_arg arg)
: base(arg)
{}
};
{};
template <>
struct traversal_archetype_impl<incrementable_traversal_tag>
@@ -175,13 +160,10 @@ namespace detail
template<class Derived, class Value>
struct archetype
{
explicit archetype(ctor_arg) {}
typedef void difference_type;
struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
typedef bogus difference_type;
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
Derived& operator++();
Derived operator++(int) const;
};
};
@@ -193,21 +175,18 @@ namespace detail
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
{
explicit archetype(ctor_arg arg)
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
{}
};
};
template <class Derived, class Value>
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// doesn't seem to pick up != from equality_comparable
template <class Derived, class Value>
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
#endif
template <>
struct traversal_archetype_impl<forward_traversal_tag>
@@ -216,9 +195,6 @@ namespace detail
struct archetype
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{
archetype()
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
{}
typedef std::ptrdiff_t difference_type;
};
};
@@ -230,8 +206,8 @@ namespace detail
struct archetype
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
{
Derived& operator--() { return static_object<Derived>::get(); }
Derived operator--(int) const { return static_object<Derived>::get(); }
Derived& operator--();
Derived operator--(int) const;
};
};
@@ -240,51 +216,33 @@ namespace detail
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
Derived& operator+=(std::ptrdiff_t);
Derived& operator-=(std::ptrdiff_t);
};
};
template <class Derived, class Value>
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t) { return static_object<Derived>::get(); }
std::ptrdiff_t);
template <class Derived, class Value>
Derived& operator+(std::ptrdiff_t,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return static_object<Derived>::get(); }
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t)
{ return static_object<Derived>::get(); }
std::ptrdiff_t);
template <class Derived, class Value>
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return 0; }
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
struct bogus_type;
@@ -328,9 +286,9 @@ struct iterator_access_archetype_impl<
typedef Value reference;
typedef Value* pointer;
value_type operator*() const { return static_object<value_type>::get(); }
value_type operator*() const;
detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
detail::arrow_proxy<Value> operator->() const;
};
};
@@ -349,7 +307,7 @@ struct iterator_access_archetype_impl<
typedef void reference;
typedef void pointer;
detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
detail::assign_proxy<Value> operator*() const;
};
};
@@ -366,7 +324,7 @@ struct iterator_access_archetype_impl<
{
typedef detail::read_write_proxy<Value> reference;
detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
detail::read_write_proxy<Value> operator*() const;
};
};
@@ -381,8 +339,8 @@ struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_itera
{
typedef Value& reference;
Value& operator*() const { return static_object<Value>::get(); }
Value* operator->() const { return 0; }
Value& operator*() const;
Value* operator->() const;
};
};
@@ -431,7 +389,7 @@ namespace detail
typedef typename detail::facade_iterator_category<
TraversalCategory
, typename mpl::eval_if<
, typename mpl::apply_if<
iterator_archetypes::has_access<
AccessCategory, iterator_archetypes::writable_iterator_t
>
@@ -485,27 +443,13 @@ struct iterator_archetype
typedef typename base::iterator_category iterator_category;
# endif
iterator_archetype() { }
iterator_archetype(iterator_archetype const& x)
: detail::iterator_archetype_base<
Value
, AccessCategory
, TraversalCategory
>(x)
{}
iterator_archetype();
iterator_archetype(iterator_archetype const&);
iterator_archetype& operator=(iterator_archetype const&)
{ return *this; }
iterator_archetype& operator=(iterator_archetype const&);
# if 0
// Optional conversion from mutable
iterator_archetype(
iterator_archetype<
typename detail::convertible_type<Value>::type
, AccessCategory
, TraversalCategory> const&
);
# endif
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
};
} // namespace boost

View File

@@ -1,7 +1,8 @@
// (C) Copyright Jeremy Siek 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
# define BOOST_ITERATOR_CATEGORIES_HPP
@@ -12,7 +13,7 @@
# include <boost/detail/workaround.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/placeholders.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
@@ -26,43 +27,19 @@ namespace boost {
//
// Traversal Categories
//
struct no_traversal_tag {};
struct incrementable_traversal_tag
: no_traversal_tag
{
// incrementable_traversal_tag() {}
// incrementable_traversal_tag(std::output_iterator_tag const&) {};
};
struct incrementable_traversal_tag {};
struct single_pass_traversal_tag
: incrementable_traversal_tag
{
// single_pass_traversal_tag() {}
// single_pass_traversal_tag(std::input_iterator_tag const&) {};
};
: incrementable_traversal_tag {};
struct forward_traversal_tag
: single_pass_traversal_tag
{
// forward_traversal_tag() {}
// forward_traversal_tag(std::forward_iterator_tag const&) {};
};
: single_pass_traversal_tag {};
struct bidirectional_traversal_tag
: forward_traversal_tag
{
// bidirectional_traversal_tag() {};
// bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {};
};
: forward_traversal_tag {};
struct random_access_traversal_tag
: bidirectional_traversal_tag
{
// random_access_traversal_tag() {};
// random_access_traversal_tag(std::random_access_iterator_tag const&) {};
};
: bidirectional_traversal_tag {};
namespace detail
{
@@ -74,19 +51,19 @@ namespace detail
//
template <class Cat>
struct old_category_to_traversal
: mpl::eval_if<
: mpl::apply_if<
is_convertible<Cat,std::random_access_iterator_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Cat,std::bidirectional_iterator_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Cat,std::forward_iterator_tag>
, mpl::identity<forward_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Cat,std::input_iterator_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Cat,std::output_iterator_tag>
, mpl::identity<incrementable_traversal_tag>
, void
@@ -97,7 +74,7 @@ namespace detail
>
{};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct old_category_to_traversal<int>
{
@@ -107,19 +84,19 @@ namespace detail
template <class Traversal>
struct pure_traversal_tag
: mpl::eval_if<
: mpl::apply_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Traversal,bidirectional_traversal_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Traversal,forward_traversal_tag>
, mpl::identity<forward_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Traversal,single_pass_traversal_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::eval_if<
, mpl::apply_if<
is_convertible<Traversal,incrementable_traversal_tag>
, mpl::identity<incrementable_traversal_tag>
, void
@@ -131,7 +108,7 @@ namespace detail
{
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct pure_traversal_tag<int>
{
@@ -147,7 +124,7 @@ namespace detail
//
template <class Cat>
struct iterator_category_to_traversal
: mpl::eval_if< // if already convertible to a traversal tag, we're done.
: mpl::apply_if< // if already convertible to a traversal tag, we're done.
is_convertible<Cat,incrementable_traversal_tag>
, mpl::identity<Cat>
, detail::old_category_to_traversal<Cat>
@@ -162,7 +139,7 @@ struct iterator_traversal
>
{};
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the

View File

@@ -1,7 +1,8 @@
// (C) Copyright Jeremy Siek 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
#define BOOST_ITERATOR_CONCEPTS_HPP
@@ -20,7 +21,6 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
@@ -31,7 +31,6 @@
// Use boost/limits to work around missing limits headers on some compilers
#include <boost/limits.hpp>
#include <boost/config.hpp>
#include <algorithm>
@@ -59,13 +58,17 @@ namespace boost_concepts {
template <typename Iterator>
class ReadableIteratorConcept {
public:
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::reference reference;
void constraints() {
boost::function_requires< boost::AssignableConcept<Iterator> >();
boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
value_type v = *i;
reference r = *i; // or perhaps read(x)
value_type v(r);
boost::ignore_unused_variable_warning(v);
}
Iterator i;
@@ -73,14 +76,18 @@ namespace boost_concepts {
template <
typename Iterator
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
, typename ValueType = typename boost::detail::iterator_traits<Iterator>::value_type
>
class WritableIteratorConcept {
public:
void constraints() {
boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
*i = v;
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
*i = v; // a good alternative could be something like write(x, v)
}
ValueType v;
Iterator i;
@@ -98,18 +105,47 @@ namespace boost_concepts {
};
template <typename Iterator>
class LvalueIteratorConcept
class ReadableLvalueIteratorConcept
{
public:
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
void constraints()
{
value_type& r = const_cast<value_type&>(*i);
boost::ignore_unused_variable_warning(r);
}
boost::function_requires< ReadableIteratorConcept<Iterator> >();
typedef boost::mpl::or_<
boost::is_same<reference, value_type&>
, boost::is_same<reference, value_type const&>
> correct_reference;
BOOST_STATIC_ASSERT(correct_reference::value);
reference v = *i;
boost::ignore_unused_variable_warning(v);
}
Iterator i;
};
template <typename Iterator>
class WritableLvalueIteratorConcept {
public:
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
void constraints() {
boost::function_requires<
ReadableLvalueIteratorConcept<Iterator> >();
boost::function_requires<
WritableIteratorConcept<Iterator, value_type> >();
boost::function_requires<
SwappableIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
}
};
//===========================================================================
// Iterator Traversal Concepts
@@ -120,8 +156,9 @@ namespace boost_concepts {
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
void constraints() {
boost::function_requires< boost::AssignableConcept<Iterator> >();
boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
BOOST_STATIC_ASSERT(
(boost::is_convertible<
@@ -163,8 +200,6 @@ namespace boost_concepts {
void constraints() {
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
typedef boost::mpl::and_<
boost::is_integral<difference_type>,
@@ -233,73 +268,109 @@ namespace boost_concepts {
//===========================================================================
// Iterator Interoperability Concept
namespace detail
{
namespace detail
{
template <typename Iterator1, typename Iterator2>
void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2)
{
bool b;
b = i1 == i2;
b = i1 != i2;
b = i2 == i1;
b = i2 != i1;
}
template <typename TraversalTag>
struct Operations;
template <typename Iterator1, typename Iterator2>
void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2,
boost::random_access_traversal_tag, boost::random_access_traversal_tag)
template <>
struct Operations<boost::incrementable_traversal_tag>
{
template <typename Iterator1, typename Iterator2>
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
{
// no interoperability constraints
}
};
template <>
struct Operations<boost::single_pass_traversal_tag>
{
template <typename Iterator1, typename Iterator2>
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
{
Operations<boost::incrementable_traversal_tag>::constraints(i1, i2);
i1 == i2;
i1 != i2;
i2 == i1;
i2 != i1;
}
};
template <>
struct Operations<boost::forward_traversal_tag>
{
template <typename Iterator1, typename Iterator2>
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
{
Operations<boost::single_pass_traversal_tag>::constraints(i1, i2);
}
};
template <>
struct Operations<boost::bidirectional_traversal_tag>
{
template <typename Iterator1, typename Iterator2>
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
{
Operations<boost::forward_traversal_tag>::constraints(i1, i2);
}
};
template <>
struct Operations<boost::random_access_traversal_tag>
{
bool b;
typename boost::detail::iterator_traits<Iterator2>::difference_type n;
b = i1 < i2;
b = i1 <= i2;
b = i1 > i2;
b = i1 >= i2;
n = i1 - i2;
b = i2 < i1;
b = i2 <= i1;
b = i2 > i1;
b = i2 >= i1;
n = i2 - i1;
}
template <typename Iterator1, typename Iterator2>
void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2,
boost::single_pass_traversal_tag, boost::single_pass_traversal_tag)
{ }
template <typename Iterator1, typename Iterator2>
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
{
Operations<boost::bidirectional_traversal_tag>::constraints(i1, i2);
i1 < i2;
i1 <= i2;
i1 > i2;
i1 >= i2;
i1 - i2;
i2 < i1;
i2 <= i1;
i2 > i1;
i2 >= i1;
i2 - i1;
}
};
} // namespace detail
template <typename Iterator, typename ConstIterator>
class InteroperableIteratorConcept
class InteroperableConcept
{
public:
typedef typename boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<
Iterator
>::type
>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
difference_type;
typedef typename boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<
ConstIterator
>::type
>::type const_traversal_category;
typedef typename boost::iterator_traversal<ConstIterator>::type
const_traversal_category;
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
const_difference_type;
void constraints()
{
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
boost::function_requires< SinglePassIteratorConcept<ConstIterator> >();
void constraints() {
BOOST_STATIC_ASSERT((boost::is_same< difference_type,
const_difference_type>::value));
BOOST_STATIC_ASSERT((boost::is_same< traversal_category,
const_traversal_category>::value));
// ToDo check what the std really requires
// detail::Operations<traversal_category>::constraints(i, ci);
detail::interop_single_pass_constraints(i, ci);
detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category());
ci = i;
ci = i;
}
Iterator i;
ConstIterator ci;
}
Iterator i;
ConstIterator ci;
};
} // namespace boost_concepts

View File

@@ -1,38 +1,30 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
#include <boost/static_assert.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/interoperable.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/implicit_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_pod.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/iterator/detail/config_def.hpp> // this goes last
@@ -44,39 +36,19 @@ namespace boost
namespace detail
{
// A binary metafunction class that always returns bool. VC6
// ICEs on mpl::always<bool>, probably because of the default
// parameters.
struct always_bool2
{
template <class T, class U>
struct apply
{
typedef bool type;
};
};
//
// enable if for use in operator implementation.
//
// enable_if_interoperable falls back to always enabled for compilers
// that don't support enable_if or is_convertible.
//
template <
class Facade1
, class Facade2
, class Return
>
struct enable_if_interoperable
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
{
typedef typename mpl::if_<
mpl::or_<
is_convertible<Facade1, Facade2>
, is_convertible<Facade2, Facade1>
>
, Return
, int[3]
>::type type;
};
#else
#ifndef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
: ::boost::iterators::enable_if<
mpl::or_<
is_convertible<Facade1, Facade2>
@@ -84,8 +56,12 @@ namespace boost
>
, Return
>
{};
#endif
{
#ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
typedef Return type;
#endif
};
//
// Generates associated types for an iterator_facade with the
@@ -105,9 +81,9 @@ namespace boost
typedef typename remove_const<ValueParam>::type value_type;
typedef typename mpl::eval_if<
typedef typename mpl::apply_if<
detail::iterator_writability_disabled<ValueParam,Reference>
, add_pointer<const value_type>
, add_pointer<typename add_const<value_type>::type>
, add_pointer<value_type>
>::type pointer;
@@ -116,185 +92,25 @@ namespace boost
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|| BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
// To interoperate with some broken library/compiler
// combinations, user-defined iterators must be derived from
// std::iterator. It is possible to implement a standard
// library for broken compilers without this limitation.
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
typedef
iterator<iterator_category, value_type, Difference, pointer, Reference>
base;
# endif
};
// iterators whose dereference operators reference the same value
// for all iterators into the same sequence (like many input
// iterators) need help with their postfix ++: the referenced
// value must be read and stored away before the increment occurs
// so that *a++ yields the originally referenced element and not
// the next one.
template <class Iterator>
class postfix_increment_proxy
{
typedef typename iterator_value<Iterator>::type value_type;
public:
explicit postfix_increment_proxy(Iterator const& x)
: stored_value(*x)
{}
// Returning a mutable reference allows nonsense like
// (*r++).mutate(), but it imposes fewer assumptions about the
// behavior of the value_type. In particular, recall taht
// (*r).mutate() is legal if operator* returns by value.
value_type&
operator*() const
{
return this->stored_value;
}
private:
mutable value_type stored_value;
};
//
// In general, we can't determine that such an iterator isn't
// writable -- we also need to store a copy of the old iterator so
// that it can be written into.
template <class Iterator>
class writable_postfix_increment_proxy
{
typedef typename iterator_value<Iterator>::type value_type;
public:
explicit writable_postfix_increment_proxy(Iterator const& x)
: stored_value(*x)
, stored_iterator(x)
{}
// Dereferencing must return a proxy so that both *r++ = o and
// value_type(*r++) can work. In this case, *r is the same as
// *r++, and the conversion operator below is used to ensure
// readability.
writable_postfix_increment_proxy const&
operator*() const
{
return *this;
}
// Provides readability of *r++
operator value_type&() const
{
return stored_value;
}
// Provides writability of *r++
template <class T>
T const& operator=(T const& x) const
{
*this->stored_iterator = x;
return x;
}
// This overload just in case only non-const objects are writable
template <class T>
T& operator=(T& x) const
{
*this->stored_iterator = x;
return x;
}
// Provides X(r++)
operator Iterator const&() const
{
return stored_iterator;
}
private:
mutable value_type stored_value;
Iterator stored_iterator;
};
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class Reference, class Value>
struct is_non_proxy_reference_impl
{
static Reference r;
template <class R>
static typename mpl::if_<
is_convertible<
R const volatile*
, Value const volatile*
>
, char[1]
, char[2]
>::type& helper(R const&);
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
};
template <class Reference, class Value>
struct is_non_proxy_reference
: mpl::bool_<
is_non_proxy_reference_impl<Reference, Value>::value
>
{};
# else
template <class Reference, class Value>
struct is_non_proxy_reference
: is_convertible<
typename remove_reference<Reference>::type
const volatile*
, Value const volatile*
>
{};
# endif
// A metafunction to choose the result type of postfix ++
//
// Because the C++98 input iterator requirements say that *r++ has
// type T (value_type), implementations of some standard
// algorithms like lexicographical_compare may use constructions
// like:
//
// *r++ < *s++
//
// If *r++ returns a proxy (as required if r is writable but not
// multipass), this sort of expression will fail unless the proxy
// supports the operator<. Since there are any number of such
// operations, we're not going to try to support them. Therefore,
// even if r++ returns a proxy, *r++ will only return a proxy if
// *r also returns a proxy.
template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
struct postfix_increment_result
: mpl::eval_if<
mpl::and_<
// A proxy is only needed for readable iterators
is_convertible<Reference,Value const&>
// No multipass iterator can have values that disappear
// before positions can be re-visited
, mpl::not_<
is_convertible<
typename iterator_category_to_traversal<CategoryOrTraversal>::type
, forward_traversal_tag
>
>
>
, mpl::if_<
is_non_proxy_reference<Reference,Value>
, postfix_increment_proxy<Iterator>
, writable_postfix_increment_proxy<Iterator>
>
, mpl::identity<Iterator>
>
{};
};
// operator->() needs special support for input iterators to strictly meet the
// standard's requirements. If *i is not a reference type, we must still
// produce a (constant) lvalue to which a pointer can be formed. We do that by
// returning an instantiation of this special proxy class template.
template <class T>
struct operator_arrow_proxy
{
@@ -309,7 +125,7 @@ namespace boost
// A metafunction that gets the result type for operator->. Also
// has a static function make() which builds the result from a
// Reference
template <class ValueType, class Reference, class Pointer>
template <class Value, class Reference, class Pointer>
struct operator_arrow_result
{
// CWPro8.3 won't accept "operator_arrow_result::type", and we
@@ -318,16 +134,16 @@ namespace boost
typedef typename mpl::if_<
is_reference<Reference>
, Pointer
, operator_arrow_proxy<ValueType>
, operator_arrow_proxy<Value>
>::type type;
static type make(Reference x)
{
return implicit_cast<type>(&x);
return type(&x);
}
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
// Deal with ETI
template<>
struct operator_arrow_result<int, int, int>
@@ -336,14 +152,13 @@ namespace boost
};
# endif
// A proxy return type for operator[], needed to deal with
// iterators that may invalidate referents upon destruction.
// Consider the temporary iterator in *(a + n)
//
// Iterator is actually an iterator_facade, so we do not have to
// go through iterator_traits to access the traits.
//
template <class Iterator>
class operator_brackets_proxy
{
// Iterator is actually an iterator_facade, so we do not have to
// go through iterator_traits to access the traits.
typedef typename Iterator::reference reference;
typedef typename Iterator::value_type value_type;
@@ -362,98 +177,48 @@ namespace boost
*m_iter = val;
return *this;
}
private:
Iterator m_iter;
};
// A metafunction that determines whether operator[] must return a
// proxy, or whether it can simply return a copy of the value_type.
template <class ValueType, class Reference>
struct use_operator_brackets_proxy
: mpl::not_<
mpl::and_<
// Really we want an is_copy_constructible trait here,
// but is_POD will have to suffice in the meantime.
boost::is_POD<ValueType>
, iterator_writability_disabled<ValueType,Reference>
>
>
{};
template <class Iterator, class Value, class Reference>
struct operator_brackets_result
{
typedef typename mpl::if_<
use_operator_brackets_proxy<Value,Reference>
iterator_writability_disabled<Value,Reference>
, Value
, operator_brackets_proxy<Iterator>
, Value
>::type type;
};
template <class Iterator>
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::false_)
{
return operator_brackets_proxy<Iterator>(iter);
}
template <class Iterator>
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::true_)
{
return *iter;
}
struct choose_difference_type
{
template <class I1, class I2>
struct apply
:
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
iterator_difference<I1>
# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
mpl::if_<
is_convertible<I2,I1>
, typename I1::difference_type
, typename I2::difference_type
>
# else
mpl::eval_if<
is_convertible<I2,I1>
, iterator_difference<I1>
, iterator_difference<I2>
>
# endif
{};
};
} // namespace detail
// Macros which describe the declarations of binary operators
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class TC1, class R1, class D1 \
, class Derived2, class V2, class TC2, class R2, class D2 \
> \
prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
operator op( \
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
# else
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class TC1, class R1, class D1 \
, class Derived2, class V2, class TC2, class R2, class D2 \
> \
prefix typename detail::enable_if_interoperable< \
Derived1, Derived2 \
, typename mpl::apply2<result_type,Derived1,Derived2>::type \
Derived1, Derived2, result_type \
>::type \
operator op( \
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
# endif
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class TC, class R, class D> \
@@ -479,8 +244,8 @@ namespace boost
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
# define BOOST_ITERATOR_FACADE_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, detail::always_bool2);
# define BOOST_ITERATOR_FACADE_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool);
BOOST_ITERATOR_FACADE_RELATION(==)
BOOST_ITERATOR_FACADE_RELATION(!=)
@@ -492,7 +257,7 @@ namespace boost
# undef BOOST_ITERATOR_FACADE_RELATION
BOOST_ITERATOR_FACADE_INTEROP_HEAD(
friend, -, detail::choose_difference_type)
friend, -, typename Derived1::difference_type)
;
BOOST_ITERATOR_FACADE_PLUS_HEAD(
@@ -503,14 +268,14 @@ namespace boost
;
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend
friend
, (typename Derived::difference_type
, iterator_facade<Derived, V, TC, R, D> const&)
)
;
# endif
template <class Facade>
static typename Facade::reference dereference(Facade const& f)
{
@@ -530,17 +295,11 @@ namespace boost
}
template <class Facade1, class Facade2>
static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
static bool equal(Facade1 const& f1, Facade2 const& f2)
{
return f1.equal(f2);
}
template <class Facade1, class Facade2>
static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
{
return f2.equal(f1);
}
template <class Facade>
static void advance(Facade& f, typename Facade::difference_type n)
{
@@ -548,32 +307,10 @@ namespace boost
}
template <class Facade1, class Facade2>
static typename Facade1::difference_type distance_from(
Facade1 const& f1, Facade2 const& f2, mpl::true_)
static typename Facade1::difference_type distance_to(
Facade1 const& f1, Facade2 const& f2)
{
return -f1.distance_to(f2);
}
template <class Facade1, class Facade2>
static typename Facade2::difference_type distance_from(
Facade1 const& f1, Facade2 const& f2, mpl::false_)
{
return f2.distance_to(f1);
}
//
// Curiously Recurring Template interface.
//
template <class I, class V, class TC, class R, class D>
static I& derived(iterator_facade<I,V,TC,R,D>& facade)
{
return *static_cast<I*>(&facade);
}
template <class I, class V, class TC, class R, class D>
static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
{
return *static_cast<I const*>(&facade);
return f1.distance_to(f2);
}
private:
@@ -598,29 +335,27 @@ namespace boost
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
# endif
{
private:
//
// Curiously Recurring Template interface.
//
typedef Derived derived_t;
Derived& derived()
{
return *static_cast<Derived*>(this);
return static_cast<Derived&>(*this);
}
Derived const& derived() const
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
return static_cast<Derived const&>(*this);
}
typedef detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
> associated_types;
protected:
// For use by derived classes
typedef iterator_facade<Derived,Value,Reference,Difference> iterator_facade_;
public:
@@ -649,14 +384,15 @@ namespace boost
>::make(*this->derived());
}
typename detail::operator_brackets_result<Derived,Value,reference>::type
typename detail::operator_brackets_result<Derived,Value,Reference>::type
operator[](difference_type n) const
{
typedef detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
typedef detail::iterator_writability_disabled<Value,Reference>
not_writable;
return detail::make_operator_brackets_result<Derived>(
this->derived() + n
, use_proxy()
, not_writable()
);
}
@@ -666,49 +402,45 @@ namespace boost
return this->derived();
}
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
operator++(int)
Derived operator++(int)
{
typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
tmp(this->derived());
Derived tmp(this->derived());
++*this;
return tmp;
}
# endif
Derived& operator--()
{
iterator_core_access::decrement(this->derived());
return this->derived();
}
Derived operator--(int)
{
Derived tmp(this->derived());
--*this;
return tmp;
}
Derived& operator+=(difference_type n)
{
iterator_core_access::advance(this->derived(), n);
return this->derived();
}
Derived& operator-=(difference_type n)
{
iterator_core_access::advance(this->derived(), -n);
return this->derived();
}
Derived operator-(difference_type x) const
{
Derived result(this->derived());
return result -= x;
}
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
// There appears to be a bug which trashes the data of classes
// derived from iterator_facade when they are assigned unless we
// define this assignment operator. This bug is only revealed
@@ -718,29 +450,11 @@ namespace boost
{
return *this;
}
# endif
# endif
};
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class I, class V, class TC, class R, class D>
typename detail::postfix_increment_result<I,V,R,TC>::type
operator++(
iterator_facade<I,V,TC,R,D>& i
, int
)
{
typename detail::postfix_increment_result<I,V,R,TC>::type
tmp(*static_cast<I*>(&i));
++i;
return tmp;
}
# endif
//
// Comparison operator implementation. The library supplied operators
// Operator implementation. The library supplied operators
// enables the user to provide fully interoperable constant/mutable
// iterator types. I.e. the library provides all operators
// for all mutable/constant iterator combinations.
@@ -749,12 +463,12 @@ namespace boost
// iterators is not required by the standard for container iterators.
// All the standard asks for is a conversion mutable -> constant.
// Most standard library implementations nowadays provide fully interoperable
// iterator implementations, but there are still heavily used implementations
// that do not provide them. (Actually it's even worse, they do not provide
// iterator implementations, but there are still heavily used implementations
// that do not provide them. (Actually it's even worse, they do not provide
// them for only a few iterators.)
//
// ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
// enable the user to turn off mixed type operators
// enable the user to turn off mixed type operators
//
// The library takes care to provide only the right operator overloads.
// I.e.
@@ -772,7 +486,7 @@ namespace boost
// deficiencies result in less strict error checking and more obscure
// error messages, functionality is not affected.
//
// For full operation compiler support for "Substitution Failure Is Not An Error"
// For full operation compiler support for "Substitution Failure Is Not An Error"
// (aka. enable_if) and boost::is_convertible is required.
//
// The following problems occur if support is lacking.
@@ -791,7 +505,7 @@ namespace boost
// // false overloads from the templated conversion constructor
// // of AdaptorA.
//
// a1 == a2;
// a1 == a2;
// ----------------
//
// AdaptorA<Iterator> a;
@@ -806,30 +520,23 @@ namespace boost
// ----------------
//
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
# define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
# else
# define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
# endif
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
{ \
/* For those compilers that do not support enable_if */ \
BOOST_STATIC_ASSERT(( \
is_interoperable< Derived1, Derived2 >::value \
)); \
return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \
, *static_cast<Derived2 const*>(&rhs) \
, BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
); \
}
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, condition, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
{ \
/* For those compilers that do not support enable_if */ \
BOOST_STATIC_ASSERT(( \
is_interoperable< Derived1, Derived2 >::value \
&& condition \
)); \
return_prefix iterator_core_access::base_op( \
static_cast<Derived2 const&>(rhs), static_cast<Derived1 const&>(lhs)); \
}
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP( \
op \
, detail::always_bool2 \
, bool \
, true \
, return_prefix \
, base_op \
)
@@ -837,22 +544,25 @@ namespace boost
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_to)
BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_to)
BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_to)
BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_to)
# undef BOOST_ITERATOR_FACADE_RELATION
// operator- requires an additional part in the static assertion
BOOST_ITERATOR_FACADE_INTEROP(
-
, detail::choose_difference_type
, typename Derived1::difference_type
, (is_same<
BOOST_DEDUCED_TYPENAME Derived1::difference_type
, BOOST_DEDUCED_TYPENAME Derived2::difference_type
>::value)
, return
, distance_from
)
, distance_to )
# undef BOOST_ITERATOR_FACADE_INTEROP
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
# define BOOST_ITERATOR_FACADE_PLUS(args) \
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
{ \
@@ -871,7 +581,7 @@ BOOST_ITERATOR_FACADE_PLUS((
))
# undef BOOST_ITERATOR_FACADE_PLUS
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

@@ -1,7 +1,8 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ITERATOR_TRAITS_DWA200347_HPP
# define ITERATOR_TRAITS_DWA200347_HPP
@@ -55,7 +56,7 @@ struct BOOST_ITERATOR_CATEGORY
typedef typename detail::iterator_traits<Iterator>::iterator_category type;
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
template <>
struct iterator_value<int>
{

View File

@@ -1,17 +1,6 @@
#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
# define BOOST_NEW_ITERATOR_TESTS_HPP
//
// Copyright (c) David Abrahams 2001.
// Copyright (c) Jeremy Siek 2001-2003.
// Copyright (c) Thomas Witt 2002.
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// This is meant to be the beginnings of a comprehensive, generic
// test suite for STL concepts such as iterators and containers.
//
@@ -39,38 +28,9 @@
# include <boost/iterator/is_lvalue_iterator.hpp>
# include <boost/iterator/detail/config_def.hpp>
# include <boost/detail/is_incrementable.hpp>
namespace boost {
// Do separate tests for *i++ so we can treat, e.g., smart pointers,
// as readable and/or writable iterators.
template <class Iterator, class T>
void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
{
T v2(*i1++);
assert(v == v2);
}
template <class Iterator, class T>
void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
{}
template <class Iterator, class T>
void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
{
++i1; // we just wrote into that position
*i1++ = v;
Iterator x(i1++);
(void)x;
}
template <class Iterator, class T>
void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
{}
// Preconditions: *i == v
template <class Iterator, class T>
void readable_iterator_test(const Iterator i1, T v)
@@ -85,8 +45,6 @@ void readable_iterator_test(const Iterator i1, T v)
assert(v2 == v);
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
// I think we don't really need this as it checks the same things as
// the above code.
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
@@ -94,18 +52,10 @@ void readable_iterator_test(const Iterator i1, T v)
}
template <class Iterator, class T>
void writable_iterator_test(Iterator i, T v, T v2)
void writable_iterator_test(Iterator i, T v)
{
Iterator i2(i); // Copy Constructible
*i2 = v;
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
writable_iterator_traversal_test(
i, v2, mpl::and_<
detail::is_incrementable<Iterator>
, detail::is_postfix_incrementable<Iterator>
>());
# endif
}
template <class Iterator>

View File

@@ -1,9 +1,10 @@
// (C) Copyright Toon Knapen 2001.
// (C) Copyright David Abrahams 2003.
// (C) Copyright Roland Richter 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#ifndef BOOST_PERMUTATION_ITERATOR_HPP
#define BOOST_PERMUTATION_ITERATOR_HPP
@@ -17,40 +18,64 @@ namespace boost
{
template< class ElementIterator
, class IndexIterator>
, class IndexIterator
, class ValueT = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default >
class permutation_iterator
: public iterator_adaptor<
permutation_iterator<ElementIterator, IndexIterator>
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
, use_default, typename detail::iterator_traits<ElementIterator>::reference>
permutation_iterator<ElementIterator, IndexIterator, ValueT, CategoryT, ReferenceT, DifferenceT>
, ElementIterator, ValueT, CategoryT, ReferenceT, DifferenceT >
{
typedef iterator_adaptor<
permutation_iterator<ElementIterator, IndexIterator>
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
, use_default, typename detail::iterator_traits<ElementIterator>::reference> super_t;
permutation_iterator<ElementIterator, IndexIterator, ValueT, CategoryT, ReferenceT, DifferenceT>
, ElementIterator, ValueT, CategoryT, ReferenceT, DifferenceT > super_t;
friend class iterator_core_access;
public:
permutation_iterator() : m_elt_iter() {}
permutation_iterator() : order_it_() {}
explicit permutation_iterator(ElementIterator x, IndexIterator y)
: super_t(y), m_elt_iter(x) {}
: super_t(x), order_it_(y) {}
template<class OtherElementIterator, class OtherIndexIterator>
template<class OtherElementIterator, class OtherIndexIterator, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OtherElementIterator, OtherIndexIterator> const& r
permutation_iterator<OtherElementIterator, OtherIndexIterator, V, C, R, D> const& r
, typename enable_if_convertible<OtherElementIterator, ElementIterator>::type* = 0
, typename enable_if_convertible<OtherIndexIterator, IndexIterator>::type* = 0
)
: super_t(r.base()), m_elt_iter(r.m_elt_iter)
: super_t(r.base())
{}
private:
typename super_t::reference dereference() const
{ return *(m_elt_iter + *this->base()); }
{ return *(this->base() + *this->order_it_); }
void increment() { ++this->order_it_; }
void decrement() { --this->order_it_; }
ElementIterator m_elt_iter;
void advance(typename super_t::difference_type n)
{
std::advance( order_it_, n );
}
template<class OtherElementIterator, class OtherIndexIterator, class V, class C, class R, class D >
typename super_t::difference_type
distance_to( permutation_iterator<OtherElementIterator, OtherIndexIterator, V, C, R, D> const& y ) const
{
return std::distance( this->order_it_, y.order_it_ );
}
template<class OtherElementIterator, class OtherIndexIterator, class V, class C, class R, class D >
bool
equal( permutation_iterator<OtherElementIterator, OtherIndexIterator, V, C, R, D> const& y ) const
{
return( y.order_it_ == this->order_it_ );
}
IndexIterator order_it_;
};

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP

View File

@@ -1,9 +1,11 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
@@ -22,13 +24,8 @@
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
# include <boost/type_traits/is_base_and_derived.hpp>
#endif
#include <boost/iterator/detail/config_def.hpp>
namespace boost
{
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
@@ -114,20 +111,12 @@ namespace boost
#endif
}
template<
class OtherUnaryFunction
, class OtherIterator
, class OtherReference
, class OtherValue>
template<class OtherIterator>
transform_iterator(
transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
transform_iterator<UnaryFunction, OtherIterator, Reference, Value> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
, typename enable_if_convertible<OtherUnaryFunction, UnaryFunction>::type* = 0
#endif
)
: super_t(t.base()), m_f(t.functor())
{}
: super_t(t.base()), m_f(t.functor()) {}
UnaryFunction functor() const
{ return m_f; }
@@ -156,16 +145,9 @@ namespace boost
// function pointer in the iterator be 0, leading to a runtime
// crash.
template <class UnaryFunction, class Iterator>
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
typename mpl::if_<
#else
typename iterators::enable_if<
#endif
is_class<UnaryFunction> // We should probably find a cheaper test than is_class<>
, transform_iterator<UnaryFunction, Iterator>
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
, int[3]
#endif
>::type
make_transform_iterator(Iterator it)
{

View File

@@ -19,7 +19,6 @@
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
# define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
#include <stddef.h>
#include <boost/iterator.hpp>
@@ -33,10 +32,14 @@
#include <boost/tuple/tuple.hpp>
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
# include <boost/type_traits/remove_cv.hpp>
#endif
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
@@ -103,13 +106,21 @@ namespace boost {
template<typename Iterator>
struct apply
{
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
typedef typename
iterator_traits<Iterator>::reference
iterator_traits<
typename boost::remove_cv<Iterator>::type
>::reference
type;
#else
typedef typename
iterator_traits<Iterator>::reference
type;
#endif
};
template<typename Iterator>
typename apply<Iterator>::type operator()(Iterator const& it)
typename apply<Iterator>::type operator()(Iterator& it)
{ return *it; }
};
@@ -141,7 +152,7 @@ namespace boost {
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform
: mpl::eval_if<
: mpl::apply_if<
boost::is_same<Tuple, tuples::null_type>
, mpl::identity<tuples::null_type>
, tuple_meta_transform_impl<Tuple, UnaryMetaFun>
@@ -180,12 +191,12 @@ namespace boost {
, typename StartType
>
struct tuple_meta_accumulate
: mpl::eval_if<
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
: mpl::apply_if<
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
mpl::or_<
#endif
boost::is_same<Tuple, tuples::null_type>
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
, boost::is_same<Tuple,int>
>
#endif
@@ -338,7 +349,7 @@ namespace boost {
typedef typename iterator_traits<Iterator>::reference type;
};
#ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
#ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
@@ -382,7 +393,7 @@ namespace boost {
>::type type;
};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
template <>
struct minimum_traversal_category_in_iterator_tuple<int>
{
@@ -401,7 +412,7 @@ namespace boost {
{
};
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. In this case I think it's an MPL bug
template<>

View File

@@ -1,10 +0,0 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef ITERATOR_ADAPTORS_DWA2004725_HPP
# define ITERATOR_ADAPTORS_DWA2004725_HPP
#define BOOST_ITERATOR_ADAPTORS_VERSION 0x0200
#include <boost/iterator/iterator_adaptor.hpp>
#endif // ITERATOR_ADAPTORS_DWA2004725_HPP

View File

@@ -1,74 +0,0 @@
// (C) Copyright Jeremy Siek 1999.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_INT_ITERATOR_H
#define BOOST_INT_ITERATOR_H
#include <boost/iterator.hpp>
#if !defined BOOST_MSVC
#include <boost/operators.hpp>
#endif
#include <iostream>
//using namespace std;
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost {
#endif
// this should use random_access_iterator_helper but I've had
// VC++ portablility problems with that. -JGS
template <class IntT>
class int_iterator
{
typedef int_iterator self;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef IntT value_type;
typedef IntT& reference;
typedef IntT* pointer;
typedef std::ptrdiff_t difference_type;
inline int_iterator() : _i(0) { }
inline int_iterator(IntT i) : _i(i) { }
inline int_iterator(const self& x) : _i(x._i) { }
inline self& operator=(const self& x) { _i = x._i; return *this; }
inline IntT operator*() { return _i; }
inline IntT operator[](IntT n) { return _i + n; }
inline self& operator++() { ++_i; return *this; }
inline self operator++(int) { self t = *this; ++_i; return t; }
inline self& operator+=(IntT n) { _i += n; return *this; }
inline self operator+(IntT n) { self t = *this; t += n; return t; }
inline self& operator--() { --_i; return *this; }
inline self operator--(int) { self t = *this; --_i; return t; }
inline self& operator-=(IntT n) { _i -= n; return *this; }
inline IntT operator-(const self& x) const { return _i - x._i; }
inline bool operator==(const self& x) const { return _i == x._i; }
// vc++ had a problem finding != in random_access_iterator_helper
// need to look into this... for now implementing everything here -JGS
inline bool operator!=(const self& x) const { return _i != x._i; }
inline bool operator<(const self& x) const { return _i < x._i; }
inline bool operator<=(const self& x) const { return _i <= x._i; }
inline bool operator>(const self& x) const { return _i > x._i; }
inline bool operator>=(const self& x) const { return _i >= x._i; }
protected:
IntT _i;
};
template <class IntT>
inline int_iterator<IntT>
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} /* namespace boost */
#endif
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost {
using ::int_iterator;
}
#endif
#endif /* BOOST_INT_ITERATOR_H */

View File

@@ -1,59 +0,0 @@
// (C) Copyright David Abrahams and Jeremy Siek 2000-2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Revision History:
// 04 Jan 2001 Factored counting_iterator stuff into
// boost/counting_iterator.hpp (David Abrahams)
#ifndef BOOST_INTEGER_RANGE_HPP_
#define BOOST_INTEGER_RANGE_HPP_
#include <boost/config.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <algorithm>
namespace boost {
//=============================================================================
// Counting Iterator and Integer Range Class
template <class IntegerType>
struct integer_range {
typedef counting_iterator<IntegerType> iterator;
typedef iterator const_iterator;
typedef IntegerType value_type;
typedef std::ptrdiff_t difference_type;
typedef IntegerType reference;
typedef IntegerType const_reference;
typedef const IntegerType* pointer;
typedef const IntegerType* const_pointer;
typedef IntegerType size_type;
integer_range(IntegerType start, IntegerType finish)
: m_start(start), m_finish(finish) { }
iterator begin() const { return iterator(m_start); }
iterator end() const { return iterator(m_finish); }
size_type size() const { return m_finish - m_start; }
bool empty() const { return m_finish == m_start; }
void swap(integer_range& x) {
std::swap(m_start, x.m_start);
std::swap(m_finish, x.m_finish);
}
protected:
IntegerType m_start, m_finish;
};
template <class IntegerType>
inline integer_range<IntegerType>
make_integer_range(IntegerType first, IntegerType last)
{
return integer_range<IntegerType>(first, last);
}
} // namespace boost
#endif // BOOST_INTEGER_RANGE_HPP_

View File

@@ -1,6 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator_adaptors.hpp>

View File

@@ -1,268 +0,0 @@
// Copyright David Abrahams and Jeremy Siek 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ITERATOR_TESTS_HPP
# define BOOST_ITERATOR_TESTS_HPP
// This is meant to be the beginnings of a comprehensive, generic
// test suite for STL concepts such as iterators and containers.
//
// Revision History:
// 28 Apr 2002 Fixed input iterator requirements.
// For a == b a++ == b++ is no longer required.
// See 24.1.1/3 for details.
// (Thomas Witt)
// 08 Feb 2001 Fixed bidirectional iterator test so that
// --i is no longer a precondition.
// (Jeremy Siek)
// 04 Feb 2001 Added lvalue test, corrected preconditions
// (David Abrahams)
# include <iterator>
# include <assert.h>
# include <boost/type_traits.hpp>
# include <boost/static_assert.hpp>
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
# include <boost/implicit_cast.hpp>
# include <boost/type_traits/broken_compiler_spec.hpp>
namespace boost {
// use this for the value type
struct dummyT {
dummyT() { }
dummyT(detail::dummy_constructor) { }
dummyT(int x) : m_x(x) { }
int foo() const { return m_x; }
bool operator==(const dummyT& d) const { return m_x == d.m_x; }
int m_x;
};
}
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
namespace boost {
// Tests whether type Iterator satisfies the requirements for a
// TrivialIterator.
// Preconditions: i != j, *i == val
template <class Iterator, class T>
void trivial_iterator_test(const Iterator i, const Iterator j, T val)
{
Iterator k;
assert(i == i);
assert(j == j);
assert(i != j);
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
T v = *i;
#else
typename std::iterator_traits<Iterator>::value_type v = *i;
#endif
assert(v == val);
#if 0
// hmm, this will give a warning for transform_iterator... perhaps
// this should be separated out into a stand-alone test since there
// are several situations where it can't be used, like for
// integer_range::iterator.
assert(v == i->foo());
#endif
k = i;
assert(k == k);
assert(k == i);
assert(k != j);
assert(*k == val);
}
// Preconditions: i != j
template <class Iterator, class T>
void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
{
*i = val;
trivial_iterator_test(i, j, val);
}
// Preconditions: *i == v1, *++i == v2
template <class Iterator, class T>
void input_iterator_test(Iterator i, T v1, T v2)
{
Iterator i1(i);
assert(i == i1);
assert(!(i != i1));
// I can see no generic way to create an input iterator
// that is in the domain of== of i and != i.
// The following works for istream_iterator but is not
// guaranteed to work for arbitrary input iterators.
//
// Iterator i2;
//
// assert(i != i2);
// assert(!(i == i2));
assert(*i1 == v1);
assert(*i == v1);
// we cannot test for equivalence of (void)++i & (void)i++
// as i is only guaranteed to be single pass.
assert(*i++ == v1);
i1 = i;
assert(i == i1);
assert(!(i != i1));
assert(*i1 == v2);
assert(*i == v2);
// i is dereferencable, so it must be incrementable.
++i;
// how to test for operator-> ?
}
// how to test output iterator?
template <bool is_pointer> struct lvalue_test
{
template <class Iterator> static void check(Iterator)
{
# ifndef BOOST_NO_STD_ITERATOR_TRAITS
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
# else
typedef typename Iterator::reference reference;
typedef typename Iterator::value_type value_type;
# endif
BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
|| boost::is_same<reference,const value_type&>::value
));
}
};
# ifdef BOOST_NO_STD_ITERATOR_TRAITS
template <> struct lvalue_test<true> {
template <class T> static void check(T) {}
};
#endif
template <class Iterator, class T>
void forward_iterator_test(Iterator i, T v1, T v2)
{
input_iterator_test(i, v1, v2);
Iterator i1 = i, i2 = i;
assert(i == i1++);
assert(i != ++i2);
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);
++i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
// borland doesn't allow non-type template parameters
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
#endif
}
// Preconditions: *i == v1, *++i == v2
template <class Iterator, class T>
void bidirectional_iterator_test(Iterator i, T v1, T v2)
{
forward_iterator_test(i, v1, v2);
++i;
Iterator i1 = i, i2 = i;
assert(i == i1--);
assert(i != --i2);
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
--i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);
}
// mutable_bidirectional_iterator_test
template <class U> struct undefined;
// Preconditions: [i,i+N) is a valid range
template <class Iterator, class TrueVals>
void random_access_iterator_test(Iterator i, int N, TrueVals vals)
{
bidirectional_iterator_test(i, vals[0], vals[1]);
const Iterator j = i;
int c;
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
for (c = 0; c < N-1; ++c) {
assert(i == j + c);
assert(*i == vals[c]);
assert(*i == boost::implicit_cast<value_type>(j[c]));
assert(*i == *(j + c));
assert(*i == *(c + j));
++i;
assert(i > j);
assert(i >= j);
assert(j <= i);
assert(j < i);
}
Iterator k = j + N - 1;
for (c = 0; c < N-1; ++c) {
assert(i == k - c);
assert(*i == vals[N - 1 - c]);
assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
Iterator q = k - c;
assert(*i == *q);
assert(i > j);
assert(i >= j);
assert(j <= i);
assert(j < i);
--i;
}
}
// Precondition: i != j
template <class Iterator, class ConstIterator>
void const_nonconst_iterator_test(Iterator i, ConstIterator j)
{
assert(i != j);
assert(j != i);
ConstIterator k(i);
assert(k == i);
assert(i == k);
k = i;
assert(k == i);
assert(i == k);
}
} // namespace boost
#endif // BOOST_ITERATOR_TESTS_HPP

View File

@@ -1,74 +0,0 @@
#ifndef POINTEE_DWA200415_HPP
# define POINTEE_DWA200415_HPP
//
// Copyright David Abrahams 2004. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// typename pointee<P>::type provides the pointee type of P.
//
// For example, it is T for T* and X for shared_ptr<X>.
//
// http://www.boost.org/libs/iterator/doc/pointee.html
//
# include <boost/detail/is_incrementable.hpp>
# include <boost/iterator/iterator_traits.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/eval_if.hpp>
namespace boost {
namespace detail
{
template <class P>
struct smart_ptr_pointee
{
typedef typename P::element_type type;
};
template <class Iterator>
struct iterator_pointee
{
typedef typename iterator_traits<Iterator>::value_type value_type;
struct impl
{
template <class T>
static char test(T const&);
static char (& test(value_type&) )[2];
static Iterator& x;
};
BOOST_STATIC_CONSTANT(bool, is_constant = sizeof(impl::test(*impl::x)) == 1);
typedef typename mpl::if_c<
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
::boost::detail::iterator_pointee<Iterator>::is_constant
# else
is_constant
# endif
, typename add_const<value_type>::type
, value_type
>::type type;
};
}
template <class P>
struct pointee
: mpl::eval_if<
detail::is_incrementable<P>
, detail::iterator_pointee<P>
, detail::smart_ptr_pointee<P>
>
{
};
} // namespace boost
#endif // POINTEE_DWA200415_HPP

View File

@@ -1,62 +0,0 @@
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
#ifndef SHARED_CONTAINER_ITERATOR_RG08102002_HPP
#define SHARED_CONTAINER_ITERATOR_RG08102002_HPP
#include "boost/iterator_adaptors.hpp"
#include "boost/shared_ptr.hpp"
#include <utility>
namespace boost {
template <typename Container>
class shared_container_iterator : public iterator_adaptor<
shared_container_iterator<Container>,
typename Container::iterator> {
typedef iterator_adaptor<
shared_container_iterator<Container>,
typename Container::iterator> super_t;
typedef typename Container::iterator iterator_t;
typedef boost::shared_ptr<Container> container_ref_t;
container_ref_t container_ref;
public:
shared_container_iterator() { }
shared_container_iterator(iterator_t const& x,container_ref_t const& c) :
super_t(x), container_ref(c) { }
};
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator iter,
boost::shared_ptr<Container> const& container) {
typedef shared_container_iterator<Container> iterator;
return iterator(iter,container);
}
template <typename Container>
std::pair<
shared_container_iterator<Container>,
shared_container_iterator<Container> >
make_shared_container_range(boost::shared_ptr<Container> const& container) {
return
std::make_pair(
make_shared_container_iterator(container->begin(),container),
make_shared_container_iterator(container->end(),container));
}
} // namespace boost
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP

50
test/Jamfile Normal file
View File

@@ -0,0 +1,50 @@
# Copyright David Abrahams 2003. Permission to copy, use,
# modify, sell and distribute this software is granted provided this
# copyright notice appears in all copies. This software is provided
# "as is" without express or implied warranty, and with no claim as
# to its suitability for any purpose.
subproject libs/iterator/test ;
import testing ;
test-suite iterator
:
# These first two tests will run last, and are expected to fail
# for many less-capable compilers.
[ compile-fail interoperable_fail.cpp ]
# test uses expected success, so that we catch unrelated
# compilation problems.
[ run is_convertible_fail.cpp ]
[ run zip_iterator_test.cpp ]
# These tests should work for just about everything.
[ compile is_lvalue_iterator.cpp ]
[ compile is_readable_iterator.cpp ]
[ run unit_tests.cpp ]
[ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ]
[ run iterator_adaptor_test.cpp ]
[ compile iterator_archetype_cc.cpp ]
[ run transform_iterator_test.cpp ]
[ run indirect_iterator_test.cpp ]
[ run filter_iterator_test.cpp ]
[ run reverse_iterator_test.cpp ]
[ run counting_iterator_test.cpp ]
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
]
[ run ../../utility/iterator_adaptor_examples.cpp ]
[ run ../../utility/counting_iterator_example.cpp ]
[ run ../../utility/filter_iterator_example.cpp ]
[ run ../../utility/fun_out_iter_example.cpp ]
[ run ../../utility/indirect_iterator_example.cpp ]
[ run ../../utility/projection_iterator_example.cpp ]
[ run ../../utility/reverse_iterator_example.cpp ]
[ run ../../utility/transform_iterator_example.cpp ]
[ run ../../utility/iterator_traits_test.cpp ]
;

44
test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,44 @@
# Copyright David Abrahams 2003. Permission to copy, use,
# modify, sell and distribute this software is granted provided this
# copyright notice appears in all copies. This software is provided
# "as is" without express or implied warranty, and with no claim as
# to its suitability for any purpose.
import testing ;
test-suite iterator
:
# These first two tests will run last, and are expected to fail
# for many less-capable compilers.
[ compile-fail interoperable_fail.cpp ]
# test uses expected success, so that we catch unrelated
# compilation problems.
[ run is_convertible_fail.cpp ]
# These tests should work for just about everything.
[ run unit_tests.cpp ]
[ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ]
[ run iterator_adaptor_test.cpp ]
[ compile iterator_archetype_cc.cpp ]
[ run transform_iterator_test.cpp ]
[ run indirect_iterator_test.cpp ]
[ run filter_iterator_test.cpp ]
[ run reverse_iterator_test.cpp ]
[ run counting_iterator_test.cpp ]
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
]
[ run zip_iterator_test.cpp ]
[ run ../../utility/iterator_adaptor_examples.cpp ]
[ run ../../utility/counting_iterator_example.cpp ]
[ run ../../utility/filter_iterator_example.cpp ]
[ run ../../utility/fun_out_iter_example.cpp ]
[ run ../../utility/indirect_iterator_example.cpp ]
[ run ../../utility/projection_iterator_example.cpp ]
[ run ../../utility/reverse_iterator_example.cpp ]
[ run ../../utility/transform_iterator_example.cpp ]
[ run ../../utility/iterator_traits_test.cpp ]
;

83
test/concept_tests.cpp Normal file
View File

@@ -0,0 +1,83 @@
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/operators.hpp>
struct new_random_access
: std::random_access_iterator_tag
, boost::random_access_traversal_tag
{};
struct new_iterator
: public boost::iterator< new_random_access, int >
{
int& operator*() const { return *m_x; }
new_iterator& operator++() { return *this; }
new_iterator operator++(int) { return *this; }
new_iterator& operator--() { return *this; }
new_iterator operator--(int) { return *this; }
new_iterator& operator+=(std::ptrdiff_t) { return *this; }
new_iterator operator+(std::ptrdiff_t) { return *this; }
new_iterator& operator-=(std::ptrdiff_t) { return *this; }
std::ptrdiff_t operator-(const new_iterator&) const { return 0; }
new_iterator operator-(std::ptrdiff_t) const { return *this; }
bool operator==(const new_iterator&) const { return false; }
bool operator!=(const new_iterator&) const { return false; }
bool operator<(const new_iterator&) const { return false; }
int* m_x;
};
new_iterator operator+(std::ptrdiff_t, new_iterator x) { return x; }
struct old_iterator
: public boost::iterator<std::random_access_iterator_tag, int>
{
int& operator*() const { return *m_x; }
old_iterator& operator++() { return *this; }
old_iterator operator++(int) { return *this; }
old_iterator& operator--() { return *this; }
old_iterator operator--(int) { return *this; }
old_iterator& operator+=(std::ptrdiff_t) { return *this; }
old_iterator operator+(std::ptrdiff_t) { return *this; }
old_iterator& operator-=(std::ptrdiff_t) { return *this; }
old_iterator operator-(std::ptrdiff_t) const { return *this; }
std::ptrdiff_t operator-(const old_iterator&) const { return 0; }
bool operator==(const old_iterator&) const { return false; }
bool operator!=(const old_iterator&) const { return false; }
bool operator<(const old_iterator&) const { return false; }
int* m_x;
};
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
int
main()
{
boost::iterator_traversal<new_iterator>::type tc;
boost::random_access_traversal_tag derived = tc;
(void)derived;
boost::function_requires<
boost_concepts::WritableLvalueIteratorConcept<int*> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<int*> >();
boost::function_requires<
boost_concepts::ReadableLvalueIteratorConcept<const int*> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<const int*> >();
boost::function_requires<
boost_concepts::WritableLvalueIteratorConcept<new_iterator> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<new_iterator> >();
boost::function_requires<
boost_concepts::WritableLvalueIteratorConcept<old_iterator> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<old_iterator> >();
return 0;
}

View File

@@ -0,0 +1,295 @@
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears in
// all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// See http://www.boost.org for most recent version including documentation.
//
// Revision History
// 16 Feb 2001 Added a missing const. Made the tests run (somewhat) with
// plain MSVC again. (David Abrahams)
// 11 Feb 2001 #if 0'd out use of counting_iterator on non-numeric types in
// MSVC without STLport, so that the other tests may proceed
// (David Abrahams)
// 04 Feb 2001 Added use of iterator_tests.hpp (David Abrahams)
// 28 Jan 2001 Removed not_an_iterator detritus (David Abrahams)
// 24 Jan 2001 Initial revision (David Abrahams)
#include <boost/config.hpp>
#ifdef __BORLANDC__ // Borland mis-detects our custom iterators
# pragma warn -8091 // template argument ForwardIterator passed to '...' is a output iterator
# pragma warn -8071 // Conversion may lose significant digits (due to counting_iterator<char> += n).
#endif
#ifdef BOOST_MSVC
# pragma warning(disable:4786) // identifier truncated in debug info
#endif
#include <boost/detail/iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/next_prior.hpp>
#include <boost/mpl/if.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/limits.hpp>
#include <algorithm>
#include <climits>
#include <iterator>
#include <stdlib.h>
#ifndef __BORLANDC__
# include <boost/tuple/tuple.hpp>
#endif
#include <vector>
#include <list>
#include <cassert>
#ifndef BOOST_NO_SLIST
# include <slist>
#endif
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
template <class T>
struct signed_assert_nonnegative
{
static void test(T x) { assert(x >= 0); }
};
template <class T>
struct unsigned_assert_nonnegative
{
static void test(T x) {}
};
template <class T>
struct assert_nonnegative
: boost::mpl::if_c<
std::numeric_limits<T>::is_signed
, signed_assert_nonnegative<T>
, unsigned_assert_nonnegative<T>
>::type
{
};
#endif
// Special tests for RandomAccess CountingIterators.
template <class CountingIterator, class Value>
void category_test(
CountingIterator start,
CountingIterator finish,
Value,
std::random_access_iterator_tag)
{
typedef typename
boost::detail::iterator_traits<CountingIterator>::difference_type
difference_type;
difference_type distance = boost::detail::distance(start, finish);
// Pick a random position internal to the range
difference_type offset = (unsigned)rand() % distance;
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
assert(offset >= 0);
#else
assert_nonnegative<difference_type>::test(offset);
#endif
CountingIterator internal = start;
std::advance(internal, offset);
// Try some binary searches on the range to show that it's ordered
assert(std::binary_search(start, finish, *internal));
// #including tuple crashed borland, so I had to give up on tie().
std::pair<CountingIterator,CountingIterator> xy(
std::equal_range(start, finish, *internal));
CountingIterator x = xy.first, y = xy.second;
assert(boost::detail::distance(x, y) == 1);
// Show that values outside the range can't be found
assert(!std::binary_search(start, boost::prior(finish), *finish));
// Do the generic random_access_iterator_test
typedef typename CountingIterator::value_type value_type;
std::vector<value_type> v;
for (value_type z = *start; !(z == *finish); ++z)
v.push_back(z);
// Note that this test requires a that the first argument is
// dereferenceable /and/ a valid iterator prior to the first argument
boost::random_access_iterator_test(start, v.size(), v.begin());
}
// Special tests for bidirectional CountingIterators
template <class CountingIterator, class Value>
void category_test(CountingIterator start, Value v1, std::bidirectional_iterator_tag)
{
Value v2 = v1;
++v2;
// Note that this test requires a that the first argument is
// dereferenceable /and/ a valid iterator prior to the first argument
boost::bidirectional_iterator_test(start, v1, v2);
}
template <class CountingIterator, class Value>
void category_test(CountingIterator start, CountingIterator finish, Value v1, std::forward_iterator_tag)
{
Value v2 = v1;
++v2;
if (finish != start && finish != boost::next(start))
boost::forward_readable_iterator_test(start, finish, v1, v2);
}
template <class CountingIterator, class Value>
void test_aux(CountingIterator start, CountingIterator finish, Value v1)
{
typedef typename CountingIterator::iterator_category category;
typedef typename CountingIterator::value_type value_type;
// If it's a RandomAccessIterator we can do a few delicate tests
category_test(start, finish, v1, category());
// Okay, brute force...
for (CountingIterator p = start
; p != finish && boost::next(p) != finish
; ++p)
{
assert(boost::next(*p) == *boost::next(p));
}
// prove that a reference can be formed to these values
typedef typename CountingIterator::value_type value;
const value* q = &*start;
(void)q; // suppress unused variable warning
}
template <class Incrementable>
void test(Incrementable start, Incrementable finish)
{
test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish), start);
}
template <class Integer>
void test_integer(Integer* = 0) // default arg works around MSVC bug
{
Integer start = 0;
Integer finish = 120;
test(start, finish);
}
template <class Integer, class Category, class Difference>
void test_integer3(Integer* = 0, Category* = 0, Difference* = 0) // default arg works around MSVC bug
{
Integer start = 0;
Integer finish = 120;
typedef boost::counting_iterator<Integer,Category,Difference> iterator;
test_aux(iterator(start), iterator(finish), start);
}
template <class Container>
void test_container(Container* = 0) // default arg works around MSVC bug
{
Container c(1 + (unsigned)rand() % 1673);
const typename Container::iterator start = c.begin();
// back off by 1 to leave room for dereferenceable value at the end
typename Container::iterator finish = start;
std::advance(finish, c.size() - 1);
test(start, finish);
typedef typename Container::const_iterator const_iterator;
test(const_iterator(start), const_iterator(finish));
}
class my_int1 {
public:
my_int1() { }
my_int1(int x) : m_int(x) { }
my_int1& operator++() { ++m_int; return *this; }
bool operator==(const my_int1& x) const { return m_int == x.m_int; }
private:
int m_int;
};
class my_int2 {
public:
typedef void value_type;
typedef void pointer;
typedef void reference;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
my_int2() { }
my_int2(int x) : m_int(x) { }
my_int2& operator++() { ++m_int; return *this; }
my_int2& operator--() { --m_int; return *this; }
bool operator==(const my_int2& x) const { return m_int == x.m_int; }
private:
int m_int;
};
class my_int3 {
public:
typedef void value_type;
typedef void pointer;
typedef void reference;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
my_int3() { }
my_int3(int x) : m_int(x) { }
my_int3& operator++() { ++m_int; return *this; }
my_int3& operator+=(std::ptrdiff_t n) { m_int += n; return *this; }
std::ptrdiff_t operator-(const my_int3& x) const { return m_int - x.m_int; }
my_int3& operator--() { --m_int; return *this; }
bool operator==(const my_int3& x) const { return m_int == x.m_int; }
bool operator!=(const my_int3& x) const { return m_int != x.m_int; }
bool operator<(const my_int3& x) const { return m_int < x.m_int; }
private:
int m_int;
};
int main()
{
// Test the built-in integer types.
test_integer<char>();
test_integer<unsigned char>();
test_integer<signed char>();
test_integer<wchar_t>();
test_integer<short>();
test_integer<unsigned short>();
test_integer<int>();
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
test_integer<long long>();
test_integer<unsigned long long>();
#endif
// Test user-defined type.
test_integer3<my_int1, std::forward_iterator_tag, int>();
test_integer<my_int2>();
test_integer<my_int3>();
// Some tests on container iterators, to prove we handle a few different categories
test_container<std::vector<int> >();
test_container<std::list<int> >();
# ifndef BOOST_NO_SLIST
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
# endif
// Also prove that we can handle raw pointers.
int array[2000];
test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));
return 0;
}

View File

@@ -0,0 +1,80 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <deque>
#include <iostream>
using boost::dummyT;
struct one_or_four
{
bool operator()(dummyT x) const
{
return x.foo() == 1 || x.foo() == 4;
}
};
template <class T> struct undefined;
// Test filter iterator
int main()
{
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 0;
}

View File

@@ -0,0 +1,209 @@
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// Revision History
// 22 Nov 2002 Thomas Witt
// Added interoperability check.
// 08 Mar 2001 Jeremy Siek
// Moved test of indirect iterator into its own file. It to
// to be in iterator_adaptor_test.cpp.
#include <boost/config.hpp>
#include <iostream>
#include <algorithm>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/concept_check.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <vector>
#include <stdlib.h>
#include <set>
#if !defined(__SGI_STL_PORT) \
&& (defined(BOOST_MSVC_STD_ITERATOR) \
|| BOOST_WORKAROUND(_CPPLIB_VER, <= 310) \
|| BOOST_WORKAROUND(__GNUC__, <= 2))
// std container random-access iterators don't support mutable/const
// interoperability (but may support const/mutable interop).
# define NO_MUTABLE_CONST_STD_SET_ITERATOR_INTEROPERABILITY
#endif
struct my_iterator_tag : public std::random_access_iterator_tag { };
using boost::dummyT;
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<dummyT>)
typedef std::vector<int> storage;
typedef std::vector<int*> pointer_ra_container;
typedef std::set<storage::iterator> iterator_set;
template <class Container>
struct indirect_iterator_pair_generator
{
typedef boost::indirect_iterator<typename Container::iterator> iterator;
typedef boost::indirect_iterator<
typename Container::iterator
, typename iterator::value_type const
> const_iterator;
};
void more_indirect_iterator_tests()
{
storage store(1000);
std::generate(store.begin(), store.end(), rand);
pointer_ra_container ptr_ra_container;
iterator_set iter_set;
for (storage::iterator p = store.begin(); p != store.end(); ++p)
{
ptr_ra_container.push_back(&*p);
iter_set.insert(p);
}
typedef indirect_iterator_pair_generator<pointer_ra_container> indirect_ra_container;
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);
indirect_ra_container::const_iterator dci = db;
assert(dci == db);
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
assert(db == dci);
#endif
assert(dci != de);
assert(dci < de);
assert(dci <= de);
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
assert(de >= dci);
assert(de > dci);
#endif
dci = de;
assert(dci == de);
boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin()));
*db = 999;
assert(store.front() == 999);
// Borland C++ is getting very confused about the typedefs here
typedef boost::indirect_iterator<iterator_set::iterator> indirect_set_iterator;
typedef boost::indirect_iterator<
iterator_set::iterator
, iterator_set::iterator::value_type const
> const_indirect_set_iterator;
indirect_set_iterator sb(iter_set.begin());
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);
*boost::prior(se) = 888;
assert(store.back() == 888);
assert(std::equal(sb, se, store.begin()));
boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
assert(std::equal(db, de, store.begin()));
}
int
main()
{
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
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(
boost::detail::has_element_type<
boost::shared_ptr<dummyT>
// std::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::InteroperableConcept<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();
}
std::cout << "test successful " << std::endl;
return 0;
}

View File

@@ -0,0 +1,22 @@
// Copyright Thomas Witt 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/concept_check.hpp>
#include <boost/cstdlib.hpp>
#include <list>
int main()
{
{
typedef boost::reverse_iterator<std::list<int*>::iterator> rev_iter;
typedef boost::indirect_iterator<std::list<int*>::iterator> ind_iter;
ind_iter() == rev_iter();
}
return boost::exit_success;
}

View File

@@ -0,0 +1,11 @@
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/cstdlib.hpp>
int main()
{
typedef boost::reverse_iterator<int*> rev_iter1;
typedef boost::reverse_iterator<char*> rev_iter2;
return boost::is_convertible<rev_iter1, rev_iter2>::value
? boost::exit_failure : boost::exit_success;
}

145
test/is_lvalue_iterator.cpp Executable file
View File

@@ -0,0 +1,145 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/iterator/is_lvalue_iterator.hpp>
#include <boost/iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
~v();
};
BOOST_TT_BROKEN_COMPILER_SPEC(v)
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
{
v operator*() const;
};
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
{
boost::noncopyable const& operator*() const;
};
template <class T>
struct proxy_iterator
: boost::iterator<std::output_iterator_tag,T>
{
typedef T value_type;
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,value_type> base;
typedef base::iterator_category iterator_category;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
operator value_type&() const;
proxy& operator=(value_type) const;
};
proxy operator*() const;
};
template <class T>
struct lvalue_iterator
{
typedef T value_type;
typedef T& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T* pointer;
T& operator*() const;
lvalue_iterator& operator++();
lvalue_iterator operator++(int);
};
template <class T>
struct constant_lvalue_iterator
{
typedef T value_type;
typedef T const& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T const* pointer;
T const& operator*() const;
constant_lvalue_iterator& operator++();
constant_lvalue_iterator operator++(int);
};
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<v>::proxy)
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<int>::proxy)
int main()
{
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
#endif
// Make sure inaccessible copy constructor doesn't prevent
// reference binding
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
#endif
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
#endif
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
return 0;
}

93
test/is_readable_iterator.cpp Executable file
View File

@@ -0,0 +1,93 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
~v();
};
BOOST_TT_BROKEN_COMPILER_SPEC(v)
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
{
v operator*() const;
};
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
{
boost::noncopyable const& operator*() const;
};
struct proxy_iterator : boost::iterator<std::output_iterator_tag,v>
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,v> base;
typedef base::iterator_category iterator_category;
typedef base::value_type value_type;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
operator v&();
proxy& operator=(v) const;
};
proxy operator*() const;
};
struct proxy_iterator2 : boost::iterator<std::output_iterator_tag,v>
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,v> base;
typedef base::iterator_category iterator_category;
typedef base::value_type value_type;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
proxy& operator=(v) const;
};
proxy operator*() const;
};
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy)
int main()
{
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<proxy_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<proxy_iterator2>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<value_iterator>::value);
// Make sure inaccessible copy constructor doesn't prevent
// readability
BOOST_STATIC_ASSERT(boost::is_readable_iterator<noncopyable_iterator>::value);
return 0;
}

View File

@@ -0,0 +1,29 @@
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/concept_check.hpp>
#include <boost/cstdlib.hpp>
#include <list>
int main()
{
{
typedef boost::reverse_iterator<int*> rev_iter;
typedef boost::reverse_iterator<int const*> c_rev_iter;
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<rev_iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<rev_iter> >();
boost::function_requires< boost::RandomAccessIteratorConcept<rev_iter> >();
boost::function_requires< boost_concepts::InteroperableConcept<rev_iter, c_rev_iter> >();
}
{
typedef boost::reverse_iterator<std::list<int>::iterator> rev_iter;
typedef boost::reverse_iterator<std::list<int>::const_iterator> c_rev_iter;
boost::function_requires< boost_concepts::ReadableLvalueIteratorConcept<c_rev_iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<c_rev_iter> >();
boost::function_requires< boost::BidirectionalIteratorConcept<c_rev_iter> >();
boost::function_requires< boost_concepts::InteroperableConcept<rev_iter, c_rev_iter> >();
}
return boost::exit_success;
}

View File

@@ -0,0 +1,323 @@
// (C) Copyright Thomas Witt 2003. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
#include <boost/config.hpp>
#include <iostream>
#include <algorithm>
#include <functional>
#include <numeric>
#include <boost/iterator/iterator_adaptor.hpp>
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
#endif
#include <boost/pending/iterator_tests.hpp>
# include <boost/type_traits/broken_compiler_spec.hpp>
#include <stdlib.h>
#include <vector>
#include <deque>
#include <set>
#include <list>
#include "static_assert_same.hpp"
#include <boost/iterator/detail/config_def.hpp>
using boost::dummyT;
struct mult_functor {
typedef int result_type;
typedef int argument_type;
// Functors used with transform_iterator must be
// DefaultConstructible, as the transform_iterator must be
// DefaultConstructible to satisfy the requirements for
// TrivialIterator.
mult_functor() { }
mult_functor(int aa) : a(aa) { }
int operator()(int b) const { return a * b; }
int a;
};
template <class Pair>
struct select1st_
: public std::unary_function<Pair, typename Pair::first_type>
{
const typename Pair::first_type& operator()(const Pair& x) const {
return x.first;
}
typename Pair::first_type& operator()(Pair& x) const {
return x.first;
}
};
struct one_or_four {
bool operator()(dummyT x) const {
return x.foo() == 1 || x.foo() == 4;
}
};
typedef std::deque<int> storage;
typedef std::deque<int*> pointer_deque;
typedef std::set<storage::iterator> iterator_set;
template <class T> struct foo;
void blah(int) { }
struct my_gen
{
typedef int result_type;
my_gen() : n(0) { }
int operator()() { return ++n; }
int n;
};
template <class V>
struct ptr_iterator
: boost::iterator_adaptor<
ptr_iterator<V>
, V*
, V
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
, V&
#endif
>
{
private:
typedef boost::iterator_adaptor<
ptr_iterator<V>
, V*
, V
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
, V&
#endif
> super_t;
public:
ptr_iterator() { }
ptr_iterator(V* d) : super_t(d) { }
template <class V2>
ptr_iterator(
const ptr_iterator<V2>& x
, typename boost::enable_if_convertible<V2*, V*>::type* = 0
)
: super_t(x.base())
{}
};
// Non-functional iterator for category modification checking
template <class Iter, class Traversal>
struct modify_traversal
: boost::iterator_adaptor<
modify_traversal<Iter, Traversal>
, Iter
, boost::use_default
, Traversal
>
{};
template <class T>
struct fwd_iterator
: boost::iterator_adaptor<
fwd_iterator<T>
, boost::forward_iterator_archetype<T>
>
{
private:
typedef boost::iterator_adaptor<
fwd_iterator<T>
, boost::forward_iterator_archetype<T>
> super_t;
public:
fwd_iterator() { }
fwd_iterator(boost::forward_iterator_archetype<T> d) : super_t(d) { }
};
template <class T>
struct in_iterator
: boost::iterator_adaptor<
in_iterator<T>
, boost::input_iterator_archetype<T>
>
{
private:
typedef boost::iterator_adaptor<
in_iterator<T>
, boost::input_iterator_archetype<T>
> super_t;
public:
in_iterator() { }
in_iterator(boost::input_iterator_archetype<T> d) : super_t(d) { }
};
template <class Iter>
struct constant_iterator
: boost::iterator_adaptor<
constant_iterator<Iter>
, Iter
, typename std::iterator_traits<Iter>::value_type const
>
{
typedef boost::iterator_adaptor<
constant_iterator<Iter>
, Iter
, typename std::iterator_traits<Iter>::value_type const
> base_t;
constant_iterator() {}
constant_iterator(Iter it)
: base_t(it) {}
};
char (& traversal2(boost::incrementable_traversal_tag) )[1];
char (& traversal2(boost::single_pass_traversal_tag ) )[2];
char (& traversal2(boost::forward_traversal_tag ) )[3];
char (& traversal2(boost::bidirectional_traversal_tag) )[4];
char (& traversal2(boost::random_access_traversal_tag) )[5];
template <class Cat>
struct traversal3
{
static typename boost::iterator_category_to_traversal<Cat>::type x;
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
typedef char (&type)[value];
};
template <class Cat>
typename traversal3<Cat>::type traversal(Cat);
template <class Iter, class Trav>
int static_assert_traversal(Iter* = 0, Trav* = 0)
{
typedef typename boost::iterator_category_to_traversal<
BOOST_DEDUCED_TYPENAME Iter::iterator_category
>::type t2;
return static_assert_same<Trav,t2>::value;
}
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<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());
}
std::cout << "test successful " << std::endl;
(void)test;
return 0;
}

View File

@@ -0,0 +1,26 @@
//
// Copyright Thomas Witt 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/concept_check.hpp>
int main()
{
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::random_access_traversal_tag
> iter;
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
return 0; // keep msvc happy
}

View File

@@ -0,0 +1,84 @@
// (C) Copyright Toon Knapen 2001.
// (C) Copyright Roland Richter 2003.
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#include <boost/config.hpp>
#include <boost/test/minimal.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/static_assert.hpp>
#include <vector>
#include <list>
#include <algorithm>
void permutation_test()
{
// Example taken from documentation of old permutation_iterator.
typedef std::vector< int > element_range_type;
typedef std::list< int > index_type;
const int element_range_size = 10;
const int index_size = 7;
BOOST_STATIC_ASSERT(index_size <= element_range_size);
element_range_type elements( element_range_size );
for( element_range_type::iterator el_it = elements.begin(); el_it != elements.end(); ++el_it )
{ *el_it = std::distance(elements.begin(), el_it); }
index_type indices( index_size );
for( index_type::iterator i_it = indices.begin(); i_it != indices.end(); ++i_it )
{ *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it); }
std::reverse( indices.begin(), indices.end() );
typedef boost::permutation_iterator< element_range_type::iterator, index_type::iterator > permutation_type;
permutation_type begin = boost::make_permutation_iterator( elements.begin(), indices.begin() );
permutation_type it = begin;
permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() );
BOOST_CHECK( it == begin );
BOOST_CHECK( it != end );
BOOST_CHECK( std::distance( begin, end ) == index_size );
for( index_type::iterator i_it1 = indices.begin(); it != end; ++i_it1, ++it )
{
BOOST_CHECK( *it == elements[ *i_it1 ] );
}
it = begin;
for( int i1 = 0; i1 < index_size - 1 ; i1+=2, it+=2 )
{
index_type::iterator i_it2 = indices.begin();
std::advance( i_it2, i1 );
BOOST_CHECK( *it == elements[ *i_it2 ] );
}
it = begin + (index_size);
for( index_type::iterator i_it3 = indices.end(); it != begin; )
{
BOOST_CHECK( *--it == elements[ *--i_it3 ] );
}
it = begin + index_size;
for( int i2 = 0; i2 < index_size - 1; i2+=2, --it )
{
index_type::iterator i_it4 = --indices.end();
std::advance( i_it4, -i2 );
BOOST_CHECK( *--it == elements[ *i_it4 ] );
}
}
int test_main(int, char *[])
{
permutation_test();
return 0;
}

View File

@@ -0,0 +1,85 @@
// Copyright Thomas Witt 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <algorithm>
#include <deque>
using boost::dummyT;
// 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);
// Test reverse_iterator_generator
{
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_generator 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(__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
}
return 0;
}

View File

@@ -0,0 +1,35 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef STATIC_ASSERT_SAME_DWA2003530_HPP
# define STATIC_ASSERT_SAME_DWA2003530_HPP
# include <boost/type.hpp>
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U>
struct static_assert_same_base;
template <class T>
struct static_assert_same_base<T,T>
{
enum { value = 1 };
};
template <class T, class U>
struct static_assert_same : static_assert_same_base<T,U> {};
#else
# include <boost/mpl/if.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/type_traits/is_same.hpp>
template <class T, class U>
struct static_assert_same
: boost::mpl::if_<boost::is_same<T,U>,boost::mpl::true_,void>::type
{};
#endif
#endif // STATIC_ASSERT_SAME_DWA2003530_HPP

View File

@@ -0,0 +1,246 @@
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// Revision History
// 22 Nov 2002 Thomas Witt
// Added interoperability check.
// 28 Oct 2002 Jeremy Siek
// Updated for new iterator adaptors.
// 08 Mar 2001 Jeremy Siek
// Moved test of transform iterator into its own file. It to
// to be in iterator_adaptor_test.cpp.
#include <boost/config.hpp>
#include <iostream>
#include <algorithm>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/pending/iterator_tests.hpp>
#include <boost/bind.hpp>
#include <boost/concept_check.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost { namespace detail
{
template<> struct function_object_result<int (*)(int)>
{
typedef int type;
};
}}
#endif
struct mult_functor {
// Functors used with transform_iterator must be
// DefaultConstructible, as the transform_iterator must be
// DefaultConstructible to satisfy the requirements for
// TrivialIterator.
mult_functor() { }
mult_functor(int aa) : a(aa) { }
int operator()(int b) const { return a * b; }
int a;
};
struct adaptable_mult_functor
: mult_functor
{
typedef int result_type;
typedef int argument_type;
// Functors used with transform_iterator must be
// DefaultConstructible, as the transform_iterator must be
// DefaultConstructible to satisfy the requirements for
// TrivialIterator.
adaptable_mult_functor() { }
adaptable_mult_functor(int aa) : mult_functor(aa) { }
};
struct select_first
{
typedef int& result_type;
int& operator()(std::pair<int, int>& p) const
{
return p.first;
}
};
struct select_second
{
typedef int& result_type;
int& operator()(std::pair<int, int>& p) const
{
return p.second;
}
};
struct const_select_first
{
typedef int const& result_type;
int const& operator()(std::pair<int, int>const& p) const
{
return p.first;
}
};
struct value_select_first
{
typedef int result_type;
int operator()(std::pair<int, int>const& p) const
{
return p.first;
}
};
int mult_2(int arg)
{
return arg*2;
}
int
main()
{
const int N = 10;
// Concept checks
{
typedef boost::transform_iterator<adaptable_mult_functor, int*> iter_t;
typedef boost::transform_iterator<adaptable_mult_functor, int const*> c_iter_t;
boost::function_requires< boost_concepts::InteroperableConcept<iter_t, c_iter_t> >();
}
// Test transform_iterator
{
int x[N], y[N];
for (int k = 0; k < N; ++k)
x[k] = k;
std::copy(x, x + N, y);
for (int k2 = 0; k2 < N; ++k2)
x[k2] = x[k2] * 2;
typedef boost::transform_iterator<adaptable_mult_functor, int*> iter_t;
iter_t i(y, adaptable_mult_functor(2));
boost::input_iterator_test(i, x[0], x[1]);
boost::input_iterator_test(iter_t(&y[0], adaptable_mult_functor(2)), x[0], x[1]);
boost::random_access_readable_iterator_test(i, N, x);
}
// Test transform_iterator non adaptable functor
{
int x[N], y[N];
for (int k = 0; k < N; ++k)
x[k] = k;
std::copy(x, x + N, y);
for (int k2 = 0; k2 < N; ++k2)
x[k2] = x[k2] * 2;
typedef boost::transform_iterator<mult_functor, int*, int> iter_t;
iter_t i(y, mult_functor(2));
boost::input_iterator_test(i, x[0], x[1]);
boost::input_iterator_test(iter_t(&y[0], mult_functor(2)), x[0], x[1]);
boost::random_access_readable_iterator_test(i, N, x);
}
// Test transform_iterator default argument handling
{
{
typedef boost::transform_iterator<adaptable_mult_functor, int*, float> iter_t;
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, float>::value));
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, float>::value));
}
{
typedef boost::transform_iterator<adaptable_mult_functor, int*, boost::use_default, float> iter_t;
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, int>::value));
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, float>::value));
}
{
typedef boost::transform_iterator<adaptable_mult_functor, int*, float, double> iter_t;
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, float>::value));
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, double>::value));
}
}
// Test transform_iterator with function pointers
{
int x[N], y[N];
for (int k = 0; k < N; ++k)
x[k] = k;
std::copy(x, x + N, y);
for (int k2 = 0; k2 < N; ++k2)
x[k2] = x[k2] * 2;
boost::input_iterator_test(
boost::make_transform_iterator(y, mult_2), x[0], x[1]);
boost::input_iterator_test(
boost::make_transform_iterator(&y[0], mult_2), x[0], x[1]);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator(y, mult_2), N, x);
}
// Test transform_iterator as projection iterator
{
typedef std::pair<int, int> pair_t;
int x[N];
int y[N];
pair_t values[N];
for(int i = 0; i < N; ++i) {
x[i] = i;
y[i] = N - (i + 1);
}
std::copy(
x
, x + N
, boost::make_transform_iterator((pair_t*)values, select_first())
);
std::copy(
y
, y + N
, boost::make_transform_iterator((pair_t*)values, select_second())
);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator((pair_t*)values, value_select_first())
, N
, x
);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator((pair_t*)values, const_select_first())
, N, x
);
boost::constant_lvalue_iterator_test(
boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
boost::non_const_lvalue_iterator_test(
boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
}
std::cout << "test successful " << std::endl;
return 0;
}

111
test/unit_tests.cpp Normal file
View File

@@ -0,0 +1,111 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/static_assert.hpp>
#include "static_assert_same.hpp"
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/iterator/detail/minimum_category.hpp>
struct X { int a; };
BOOST_TT_BROKEN_COMPILER_SPEC(X)
struct Xiter : boost::iterator_adaptor<Xiter,X*>
{
Xiter();
Xiter(X* p) : boost::iterator_adaptor<Xiter, X*>(p) {}
};
void take_xptr(X*) {}
void operator_arrow_test()
{
// check that the operator-> result is a pointer for lvalue iterators
X x;
take_xptr(Xiter(&x).operator->());
}
template <class T, class U, class Min>
struct static_assert_min_cat
: static_assert_same<
typename boost::detail::minimum_category<T,U>::type, Min
>
{};
void category_test()
{
using namespace boost;
using namespace boost::detail;
BOOST_STATIC_ASSERT((
!boost::is_convertible<
std::input_iterator_tag
, input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
!boost::is_convertible<
std::output_iterator_tag
, input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
boost::is_convertible<
input_output_iterator_tag
, std::input_iterator_tag>::value));
BOOST_STATIC_ASSERT((
boost::is_convertible<
input_output_iterator_tag
, std::output_iterator_tag>::value));
#if 0 // This seems wrong; we're not advertising
// input_output_iterator_tag are we?
BOOST_STATIC_ASSERT((
boost::is_convertible<
std::forward_iterator_tag
, input_output_iterator_tag>::value));
#endif
int test = static_assert_min_cat<
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
>::value;
test = static_assert_min_cat<
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
>::value;
#if 0
test = static_assert_min_cat<
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
>::value;
#endif
test = static_assert_min_cat<
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
>::value;
test = static_assert_min_cat<
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
>::value;
#if 0 // This would be wrong: a random access iterator is not
// neccessarily writable, as is an output iterator.
test = static_assert_min_cat<
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
>::value;
#endif
(void)test;
}
int main()
{
category_test();
operator_arrow_test();
return 0;
}

910
test/zip_iterator_test.cpp Executable file
View File

@@ -0,0 +1,910 @@
// (C) Copyright Dave Abrahams and Thomas Becker 2003. Permission to
// copy, use, modify, sell and distribute this software is granted
// provided this copyright notice appears in all copies. This software
// is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
//
// File:
// =====
// zip_iterator_test_main.cpp
// Author:
// =======
// Thomas Becker
// Created:
// ========
// Jul 15, 2003
// Purpose:
// ========
// Test driver for zip_iterator.hpp
// Compilers Tested:
// =================
// Metrowerks Codewarrior Pro 7.2, 8.3
// gcc 2.95.3
// gcc 3.2
// Microsoft VC 6sp5 (test fails due to some compiler bug)
// Microsoft VC 7 (works)
// Microsoft VC 7.1
// Intel 5
// Intel 6
// Intel 7.1
// Intel 8
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
/////////////////////////////////////////////////////////////////////////////
//
// Includes
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/iterator/zip_iterator.hpp>
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/workaround.hpp>
#include <stddef.h>
template <class It>
struct pure_traversal
: boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<It>::type
>
{};
/////////////////////////////////////////////////////////////////////////////
//
// Das Main Funktion
//
/////////////////////////////////////////////////////////////////////////////
int main( void )
{
std::cout << "\n"
<< "***********************************************\n"
<< "* *\n"
<< "* Test driver for boost::zip_iterator *\n"
<< "* Copyright Thomas Becker 2003 *\n"
<< "* *\n"
<< "***********************************************\n\n"
<< std::flush;
size_t num_successful_tests = 0;
size_t num_failed_tests = 0;
/////////////////////////////////////////////////////////////////////////////
//
// Make sure tuples are supported
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Basic tuple support: "
<< std::flush;
typedef boost::tuples::tuple<int, double> mytuple;
mytuple t1;
boost::tuples::get<0>(t1) = 42;
boost::tuples::get<1>(t1) = 42.1;
if( 2 == boost::tuples::length<mytuple>::value &&
42 == boost::tuples::get<0>(t1) &&
42.1 == boost::tuples::get<1>(t1)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Make sure iterator adaptor is supported
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Basic iterator adaptor support: "
<< std::flush;
std::set<int> s;
s.insert(42);
s.insert(43);
s.insert(44);
typedef boost::transform_iterator<
std::binder1st<std::plus<int> >,
std::set<int>::iterator
>
add_seven_iterator;
typedef boost::transform_iterator<
std::binder1st<std::plus<int> >,
std::set<int>::const_iterator
>
const_add_seven_iterator;
add_seven_iterator set_run(s.begin(), std::bind1st(std::plus<int>(), 7));
add_seven_iterator set_end(s.end(), std::bind1st(std::plus<int>(), 7));
const_add_seven_iterator const_set_run(s.begin(), std::bind1st(std::plus<int>(), 7));
// set_run = const_set_run; // Error: can't convert from const to non-const
const_set_run = set_run;
if( 49 == *set_run &&
50 == *++set_run &&
51 == *++set_run &&
set_end == ++set_run &&
49 == *const_set_run &&
50 == *++const_set_run &&
51 == *++const_set_run &&
set_end == ++const_set_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator construction and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator construction and dereferencing: "
<< std::flush;
std::vector<double> vect1(3);
vect1[0] = 42.;
vect1[1] = 43.;
vect1[2] = 44.;
std::set<int> intset;
intset.insert(52);
intset.insert(53);
intset.insert(54);
//
boost::zip_iterator<
boost::tuples::tuple<
std::set<int>::iterator
, std::vector<double>::iterator
>
>
zip_it_mixed(
boost::make_tuple(
intset.begin()
, vect1.begin()
)
);
boost::tuples::tuple<int, double> val_tuple(
*zip_it_mixed);
boost::tuples::tuple<const int&, double&> ref_tuple(
*zip_it_mixed);
double dblOldVal = boost::tuples::get<1>(ref_tuple);
boost::tuples::get<1>(ref_tuple) -= 41.;
if( 52 == boost::tuples::get<0>(val_tuple) &&
42. == boost::tuples::get<1>(val_tuple) &&
52 == boost::tuples::get<0>(ref_tuple) &&
1. == boost::tuples::get<1>(ref_tuple) &&
1. == *vect1.begin()
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
// Undo change to vect1
boost::tuples::get<1>(ref_tuple) = dblOldVal;
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator with 12 components
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterators with 12 components: "
<< std::flush;
// Declare 12 containers
//
std::list<int> li1;
li1.push_back(1);
std::set<int> se1;
se1.insert(2);
std::vector<int> ve1;
ve1.push_back(3);
//
std::list<int> li2;
li2.push_back(4);
std::set<int> se2;
se2.insert(5);
std::vector<int> ve2;
ve2.push_back(6);
//
std::list<int> li3;
li3.push_back(7);
std::set<int> se3;
se3.insert(8);
std::vector<int> ve3;
ve3.push_back(9);
//
std::list<int> li4;
li4.push_back(10);
std::set<int> se4;
se4.insert(11);
std::vector<int> ve4;
ve4.push_back(12);
// typedefs for cons lists of iterators.
typedef boost::tuples::cons<
std::set<int>::iterator,
boost::tuples::tuple<
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::const_iterator
>::inherited
> cons_11_its_type;
//
typedef boost::tuples::cons<
std::list<int>::const_iterator,
cons_11_its_type
> cons_12_its_type;
// typedefs for cons lists for dereferencing the zip iterator
// made from the cons list above.
typedef boost::tuples::cons<
const int&,
boost::tuples::tuple<
int&,
int&,
const int&,
int&,
int&,
const int&,
int&,
int&,
const int&,
const int&
>::inherited
> cons_11_refs_type;
//
typedef boost::tuples::cons<
const int&,
cons_11_refs_type
> cons_12_refs_type;
// typedef for zip iterator with 12 elements
typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type;
// Declare a 12-element zip iterator.
zip_it_12_type zip_it_12(
cons_12_its_type(
li1.begin(),
cons_11_its_type(
se1.begin(),
boost::make_tuple(
ve1.begin(),
li2.begin(),
se2.begin(),
ve2.begin(),
li3.begin(),
se3.begin(),
ve3.begin(),
li4.begin(),
se4.begin(),
ve4.begin()
)
)
)
);
// Dereference, mess with the result a little.
cons_12_refs_type zip_it_12_dereferenced(*zip_it_12);
boost::tuples::get<9>(zip_it_12_dereferenced) = 42;
// Make a copy and move it a little to force some instantiations.
zip_it_12_type zip_it_12_copy(zip_it_12);
++zip_it_12_copy;
if( boost::tuples::get<11>(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
boost::tuples::get<11>(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
1 == boost::tuples::get<0>(zip_it_12_dereferenced) &&
12 == boost::tuples::get<11>(zip_it_12_dereferenced) &&
42 == *(li4.begin())
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator incrementing and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator ++ and *: "
<< std::flush;
std::vector<double> vect2(3);
vect2[0] = 2.2;
vect2[1] = 3.3;
vect2[2] = 4.4;
boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_begin(
boost::make_tuple(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_run(
boost::make_tuple(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_end(
boost::make_tuple(
vect1.end(),
vect2.end()
)
);
if( zip_it_run == zip_it_begin &&
42. == boost::tuples::get<0>(*zip_it_run) &&
2.2 == boost::tuples::get<1>(*zip_it_run) &&
43. == boost::tuples::get<0>(*(++zip_it_run)) &&
3.3 == boost::tuples::get<1>(*zip_it_run) &&
44. == boost::tuples::get<0>(*(++zip_it_run)) &&
4.4 == boost::tuples::get<1>(*zip_it_run) &&
zip_it_end == ++zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator decrementing and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator -- and *: "
<< std::flush;
if( zip_it_run == zip_it_end &&
zip_it_end == zip_it_run-- &&
44. == boost::tuples::get<0>(*zip_it_run) &&
4.4 == boost::tuples::get<1>(*zip_it_run) &&
43. == boost::tuples::get<0>(*(--zip_it_run)) &&
3.3 == boost::tuples::get<1>(*zip_it_run) &&
42. == boost::tuples::get<0>(*(--zip_it_run)) &&
2.2 == boost::tuples::get<1>(*zip_it_run) &&
zip_it_begin == zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator copy construction and equality
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator copy construction and equality: "
<< std::flush;
boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
> zip_it_run_copy(zip_it_run);
if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator inequality
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator inequality: "
<< std::flush;
if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator less than
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator less than: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run + 1
//
if( zip_it_run < zip_it_run_copy &&
!( zip_it_run < --zip_it_run_copy) &&
zip_it_run == zip_it_run_copy
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator less than or equal
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "zip iterator less than or equal: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run
//
++zip_it_run;
zip_it_run_copy += 2;
if( zip_it_run <= zip_it_run_copy &&
zip_it_run <= --zip_it_run_copy &&
!( zip_it_run <= --zip_it_run_copy) &&
zip_it_run <= zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator greater than
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator greater than: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run - 1
//
if( zip_it_run > zip_it_run_copy &&
!( zip_it_run > ++zip_it_run_copy) &&
zip_it_run == zip_it_run_copy
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator greater than or equal
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator greater than or equal: "
<< std::flush;
++zip_it_run;
// Note: zip_it_run == zip_it_run_copy + 1
//
if( zip_it_run >= zip_it_run_copy &&
--zip_it_run >= zip_it_run_copy &&
! (zip_it_run >= ++zip_it_run_copy)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator + int
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator + int: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy - 1
//
zip_it_run = zip_it_run + 2;
++zip_it_run_copy;
if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator - int
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator - int: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy, and both are at end position
//
zip_it_run = zip_it_run - 2;
--zip_it_run_copy;
--zip_it_run_copy;
if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator +=
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator +=: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy, and both are at begin + 1
//
zip_it_run += 2;
if( zip_it_run == zip_it_begin + 3 )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator -=
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator -=: "
<< std::flush;
// Note: zip_it_run is at end position, zip_it_run_copy is at
// begin plus one.
//
zip_it_run -= 2;
if( zip_it_run == zip_it_run_copy )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator getting member iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator member iterators: "
<< std::flush;
// Note: zip_it_run and zip_it_run_copy are both at
// begin plus one.
//
if( boost::tuples::get<0>(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
boost::tuples::get<1>(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Making zip iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Making zip iterators: "
<< std::flush;
std::vector<boost::tuples::tuple<double, double> >
vect_of_tuples(3);
std::copy(
boost::make_zip_iterator(
boost::make_tuple(
vect1.begin(),
vect2.begin()
)
),
boost::make_zip_iterator(
boost::make_tuple(
vect1.end(),
vect2.end()
)
),
vect_of_tuples.begin()
);
if( 42. == boost::tuples::get<0>(*vect_of_tuples.begin()) &&
2.2 == boost::tuples::get<1>(*vect_of_tuples.begin()) &&
43. == boost::tuples::get<0>(*(vect_of_tuples.begin() + 1)) &&
3.3 == boost::tuples::get<1>(*(vect_of_tuples.begin() + 1)) &&
44. == boost::tuples::get<0>(*(vect_of_tuples.begin() + 2)) &&
4.4 == boost::tuples::get<1>(*(vect_of_tuples.begin() + 2))
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator non-const --> const conversion
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator non-const to const conversion: "
<< std::flush;
boost::zip_iterator<
boost::tuples::tuple<
std::set<int>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_const(
boost::make_tuple(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
boost::tuples::tuple<
std::set<int>::iterator,
std::vector<double>::const_iterator
>
>
zip_it_half_const(
boost::make_tuple(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
boost::tuples::tuple<
std::set<int>::iterator,
std::vector<double>::iterator
>
>
zip_it_non_const(
boost::make_tuple(
intset.begin(),
vect2.begin()
)
);
zip_it_half_const = ++zip_it_non_const;
zip_it_const = zip_it_half_const;
++zip_it_const;
// zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const
if( 54 == boost::tuples::get<0>(*zip_it_const) &&
4.4 == boost::tuples::get<1>(*zip_it_const) &&
53 == boost::tuples::get<0>(*zip_it_half_const) &&
3.3 == boost::tuples::get<1>(*zip_it_half_const)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator categories
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator categories: "
<< std::flush;
// The big iterator of the previous test has vector, list, and set iterators.
// Therefore, it must be bidirectional, but not random access.
bool bBigItIsBidirectionalIterator = boost::is_convertible<
boost::iterator_traversal<zip_it_12_type>::type
, boost::bidirectional_traversal_tag
>::value;
bool bBigItIsRandomAccessIterator = boost::is_convertible<
boost::iterator_traversal<zip_it_12_type>::type
, boost::random_access_traversal_tag
>::value;
// A combining iterator with all vector iterators must have random access
// traversal.
//
typedef boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
> all_vects_type;
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
boost::iterator_traversal<all_vects_type>::type
, boost::random_access_traversal_tag
>::value;
// The big test.
if( bBigItIsBidirectionalIterator &&
! bBigItIsRandomAccessIterator &&
bAllVectsIsRandomAccessIterator
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
// Done
//
std::cout << "\nTest Result:"
<< "\n============"
<< "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests)
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
<< std::endl;
return num_failed_tests;
}