mirror of
https://github.com/boostorg/iterator.git
synced 2026-01-26 06:32:22 +00:00
Compare commits
7 Commits
boost-1.32
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bedcfb875a | ||
|
|
4fe621f006 | ||
|
|
3435dc29ab | ||
|
|
3b60f75bc6 | ||
|
|
a8f528130a | ||
|
|
c0788f2cd8 | ||
|
|
c6bc3b2547 |
@@ -16,7 +16,5 @@ test-suite iterator_examples
|
||||
[ run indirect_iterator_example.cpp ]
|
||||
[ run permutation_iter_example.cpp ]
|
||||
[ run reverse_iterator_example.cpp ]
|
||||
[ run projection_iterator_example.cpp ]
|
||||
[ run transform_iterator_example.cpp ]
|
||||
|
||||
;
|
||||
;
|
||||
|
||||
@@ -21,13 +21,6 @@ int main(int, char*[])
|
||||
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using make_counting_iterator()
|
||||
std::cout << "counting from -5 to 4:" << std::endl;
|
||||
std::copy(boost::make_counting_iterator(-5),
|
||||
boost::make_counting_iterator(5),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using counting iterator to create an array of pointers.
|
||||
int N = 7;
|
||||
std::vector<int> numbers;
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 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)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
struct personnel_record {
|
||||
personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
|
||||
std::string m_name;
|
||||
int m_ID;
|
||||
};
|
||||
|
||||
struct select_name {
|
||||
typedef personnel_record argument_type;
|
||||
typedef std::string const& result_type;
|
||||
const std::string& operator()(const personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
std::string& operator()(personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct select_ID {
|
||||
typedef personnel_record argument_type;
|
||||
typedef int& result_type;
|
||||
const int& operator()(const personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
int& operator()(personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::list<personnel_record> personnel_list;
|
||||
|
||||
personnel_list.push_back(personnel_record("Barney", 13423));
|
||||
personnel_list.push_back(personnel_record("Fred", 12343));
|
||||
personnel_list.push_back(personnel_record("Wilma", 62454));
|
||||
personnel_list.push_back(personnel_record("Betty", 20490));
|
||||
|
||||
// Example of using transform_iterator to print out the names in the
|
||||
// personnel list using a projection.
|
||||
|
||||
boost::transform_iterator<
|
||||
select_name
|
||||
, std::list<personnel_record>::iterator
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
, std::string
|
||||
#endif
|
||||
>
|
||||
personnel_first(personnel_list.begin()),
|
||||
personnel_last(personnel_list.end());
|
||||
|
||||
std::copy(personnel_first, personnel_last,
|
||||
std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using transform_iterator with const_iterators to
|
||||
// assign new ID numbers to the personnel.
|
||||
|
||||
boost::transform_iterator<
|
||||
select_ID, std::list<personnel_record>::iterator
|
||||
> ID_first(personnel_list.begin()),
|
||||
ID_last(personnel_list.end());
|
||||
|
||||
int new_id = 0;
|
||||
while (ID_first != ID_last) {
|
||||
*ID_first = new_id++;
|
||||
++ID_first;
|
||||
}
|
||||
|
||||
boost::transform_iterator<
|
||||
select_ID, std::list<personnel_record>::const_iterator, int const&
|
||||
>
|
||||
const_ID_first(personnel_list.begin()),
|
||||
const_ID_last(personnel_list.end());
|
||||
|
||||
std::copy(const_ID_first, const_ID_last,
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// Example of using make_transform_iterator()
|
||||
// to print out the names in the personnel list again.
|
||||
std::copy(
|
||||
boost::make_transform_iterator<select_name>(personnel_list.begin())
|
||||
, boost::make_transform_iterator<select_name>(personnel_list.end())
|
||||
, std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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
|
||||
@@ -22,7 +22,11 @@
|
||||
# define BOOST_ITERATOR_CONFIG_DEF
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
// 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) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
|
||||
|
||||
// Recall that in general, compilers without partial specialization
|
||||
@@ -36,7 +40,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 neccessary. Not sure how best to resolve this one.
|
||||
// strictly necessary. Not sure how best to resolve this one.
|
||||
|
||||
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
|
||||
|
||||
@@ -44,7 +48,8 @@
|
||||
|
||||
#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(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|
||||
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
|
||||
# define BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
|
||||
# if 0 // test code
|
||||
|
||||
@@ -31,9 +31,9 @@ namespace boost
|
||||
, typename mpl::if_<
|
||||
is_convertible<
|
||||
typename iterator_traversal<Iterator>::type
|
||||
, bidirectional_traversal_tag
|
||||
, random_access_traversal_tag
|
||||
>
|
||||
, forward_traversal_tag
|
||||
, bidirectional_traversal_tag
|
||||
, use_default
|
||||
>::type
|
||||
> type;
|
||||
|
||||
@@ -278,6 +278,8 @@ namespace boost
|
||||
{
|
||||
}
|
||||
|
||||
typedef Base base_type;
|
||||
|
||||
Base const& base() const
|
||||
{ return m_iterator; }
|
||||
|
||||
|
||||
@@ -240,8 +240,7 @@ namespace detail
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, bidirectional_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(); }
|
||||
@@ -272,6 +271,21 @@ namespace detail
|
||||
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; }
|
||||
|
||||
struct bogus_type;
|
||||
|
||||
template <class Value>
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#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>
|
||||
@@ -16,6 +14,9 @@
|
||||
#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>
|
||||
@@ -106,7 +107,7 @@ namespace boost
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
detail::iterator_writability_disabled<ValueParam,Reference>
|
||||
, add_pointer<typename add_const<value_type>::type>
|
||||
, add_pointer<const value_type>
|
||||
, add_pointer<value_type>
|
||||
>::type pointer;
|
||||
|
||||
@@ -269,8 +270,8 @@ namespace boost
|
||||
struct postfix_increment_result
|
||||
: mpl::eval_if<
|
||||
mpl::and_<
|
||||
// A proxy is only needed for readable iterators
|
||||
is_convertible<Reference,Value>
|
||||
// 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
|
||||
@@ -322,7 +323,7 @@ namespace boost
|
||||
|
||||
static type make(Reference x)
|
||||
{
|
||||
return type(&x);
|
||||
return implicit_cast<type>(&x);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
// 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>
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
// 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)
|
||||
#ifndef POINTEE_DWA200415_HPP
|
||||
# define POINTEE_DWA200415_HPP
|
||||
|
||||
// dereferenceable_traits provides access to the value_type and
|
||||
// reference of a Dereferenceable type.
|
||||
|
||||
# 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
|
||||
@@ -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
|
||||
11
test/Jamfile
11
test/Jamfile
@@ -46,8 +46,17 @@ test-suite iterator
|
||||
[ run reverse_iterator_test.cpp ]
|
||||
[ run counting_iterator_test.cpp ]
|
||||
[ run interoperable.cpp ]
|
||||
[ run iterator_traits_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 ]
|
||||
[ run ../../utility/shared_iterator_test.cpp ]
|
||||
;
|
||||
|
||||
@@ -44,4 +44,14 @@ test-suite iterator
|
||||
[ 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 ]
|
||||
[ run ../../utility/shared_iterator_test.cpp ]
|
||||
;
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 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)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <boost/iterator/indirect_iterator.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
char characters[] = "abcdefg";
|
||||
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
|
||||
char* pointers_to_chars[N]; // at the end.
|
||||
for (int i = 0; i < N; ++i)
|
||||
pointers_to_chars[i] = &characters[i];
|
||||
|
||||
// Example of using indirect_iterator_generator
|
||||
|
||||
boost::indirect_iterator<char**, char>
|
||||
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
// Example of using indirect_iterator_pair_generator
|
||||
|
||||
char mutable_characters[N];
|
||||
char* pointers_to_mutable_chars[N];
|
||||
for (int j = 0; j < N; ++j)
|
||||
pointers_to_mutable_chars[j] = &mutable_characters[j];
|
||||
|
||||
boost::indirect_iterator<char* const*> mutable_indirect_first(pointers_to_mutable_chars),
|
||||
mutable_indirect_last(pointers_to_mutable_chars + N);
|
||||
boost::indirect_iterator<char* const*, char const> const_indirect_first(pointers_to_chars),
|
||||
const_indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::transform(const_indirect_first, const_indirect_last,
|
||||
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
||||
|
||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
// Example of using make_indirect_iterator()
|
||||
|
||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
// (C) Copyright David Abrahams 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)
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
|
||||
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
|
||||
// on MSVC. Reordered some #ifdefs for coherency.
|
||||
// (David Abrahams)
|
||||
// 13 Feb 2001 Test new VC6 workarounds (David Abrahams)
|
||||
// 11 Feb 2001 Final fixes for Borland (David Abrahams)
|
||||
// 11 Feb 2001 Some fixes for Borland get it closer on that compiler
|
||||
// (David Abrahams)
|
||||
// 07 Feb 2001 More comprehensive testing; factored out static tests for
|
||||
// better reuse (David Abrahams)
|
||||
// 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a
|
||||
// reference type from operator* (David Abrahams)
|
||||
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
// A UDT for which we can specialize std::iterator_traits<element*> on
|
||||
// compilers which don't support partial specialization. There's no
|
||||
// other reasonable way to test pointers on those compilers.
|
||||
struct element {};
|
||||
|
||||
// An iterator for which we can get traits.
|
||||
struct my_iterator1
|
||||
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
|
||||
{
|
||||
my_iterator1(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator1& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator1& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Used to prove that we don't require std::iterator<> in the hierarchy under
|
||||
// MSVC6, and that we can compute all the traits for a standard-conforming UDT
|
||||
// iterator.
|
||||
struct my_iterator2
|
||||
: boost::equality_comparable<my_iterator2
|
||||
, boost::incrementable<my_iterator2
|
||||
, boost::dereferenceable<my_iterator2,const char*> > >
|
||||
{
|
||||
typedef char value_type;
|
||||
typedef long difference_type;
|
||||
typedef const char* pointer;
|
||||
typedef const char& reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
my_iterator2(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator2& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator2& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Used to prove that we're not overly confused by the existence of
|
||||
// std::iterator<> in the hierarchy under MSVC6 - we should find that
|
||||
// boost::detail::iterator_traits<my_iterator3>::difference_type is int.
|
||||
struct my_iterator3 : my_iterator1
|
||||
{
|
||||
typedef int difference_type;
|
||||
my_iterator3(const char* p)
|
||||
: my_iterator1(p) {}
|
||||
};
|
||||
|
||||
//
|
||||
// Assertion tools. Used instead of BOOST_STATIC_ASSERT because that
|
||||
// doesn't give us a nice stack backtrace
|
||||
//
|
||||
template <bool = false> struct assertion;
|
||||
|
||||
template <> struct assertion<true>
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct assert_same
|
||||
: assertion<(::boost::is_same<T,U>::value)>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// Iterator tests
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_portable_tests
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::pointer test_pt;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
|
||||
typedef typename assert_same<test_pt, pointer>::type a1;
|
||||
typedef typename assert_same<test_rt, reference>::type a2;
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct portable_tests
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat;
|
||||
typedef typename assert_same<test_dt, difference_type>::type a1;
|
||||
typedef typename assert_same<test_cat, category>::type a2;
|
||||
};
|
||||
|
||||
// Test iterator_traits
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct input_iterator_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt;
|
||||
typedef typename assert_same<test_vt, value_type>::type a1;
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_pointer_test
|
||||
: input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct maybe_pointer_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
};
|
||||
|
||||
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
|
||||
istream_iterator_test;
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
|
||||
typedef ::std::char_traits<char>::off_type distance;
|
||||
non_pointer_test<std::ostream_iterator<int>,int,
|
||||
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
||||
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
int, void, int*, int&, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#else
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
void, void, void, void, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __KCC
|
||||
typedef long std_list_diff_type;
|
||||
#else
|
||||
typedef std::ptrdiff_t std_list_diff_type;
|
||||
#endif
|
||||
|
||||
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
|
||||
list_iterator_test;
|
||||
|
||||
maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
vector_iterator_test;
|
||||
|
||||
maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
int_pointer_test;
|
||||
|
||||
non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator1_test;
|
||||
|
||||
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator2_test;
|
||||
|
||||
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator3_test;
|
||||
|
||||
int main()
|
||||
{
|
||||
char chars[100];
|
||||
int ints[100];
|
||||
|
||||
for (int length = 3; length < 100; length += length / 3)
|
||||
{
|
||||
std::list<int> l(length);
|
||||
assert(boost::detail::distance(l.begin(), l.end()) == length);
|
||||
|
||||
std::vector<int> v(length);
|
||||
assert(boost::detail::distance(v.begin(), v.end()) == length);
|
||||
|
||||
assert(boost::detail::distance(&ints[0], ints + length) == length);
|
||||
assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user