forked from boostorg/iterator
move over iterator adaptor examples from 'utility'
[SVN r25979]
This commit is contained in:
19
test/Jamfile
19
test/Jamfile
@ -46,17 +46,16 @@ test-suite iterator
|
|||||||
[ run reverse_iterator_test.cpp ]
|
[ run reverse_iterator_test.cpp ]
|
||||||
[ run counting_iterator_test.cpp ]
|
[ run counting_iterator_test.cpp ]
|
||||||
[ run interoperable.cpp ]
|
[ run interoperable.cpp ]
|
||||||
|
[ run iterator_traits_test.cpp ]
|
||||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||||
]
|
]
|
||||||
|
|
||||||
[ run ../../utility/iterator_adaptor_examples.cpp ]
|
[ run iterator_adaptor_examples.cpp ]
|
||||||
[ run ../../utility/counting_iterator_example.cpp ]
|
[ run counting_iterator_example.cpp ]
|
||||||
[ run ../../utility/filter_iterator_example.cpp ]
|
[ run filter_iterator_example.cpp ]
|
||||||
[ run ../../utility/fun_out_iter_example.cpp ]
|
[ run fun_out_iter_example.cpp ]
|
||||||
[ run ../../utility/indirect_iterator_example.cpp ]
|
[ run indirect_iterator_example.cpp ]
|
||||||
[ run ../../utility/projection_iterator_example.cpp ]
|
[ run projection_iterator_example.cpp ]
|
||||||
[ run ../../utility/reverse_iterator_example.cpp ]
|
[ run reverse_iterator_example.cpp ]
|
||||||
[ run ../../utility/transform_iterator_example.cpp ]
|
[ run transform_iterator_example.cpp ]
|
||||||
[ run ../../utility/iterator_traits_test.cpp ]
|
|
||||||
[ run ../../utility/shared_iterator_test.cpp ]
|
|
||||||
;
|
;
|
||||||
|
60
test/counting_iterator_example.cpp
Normal file
60
test/counting_iterator_example.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// (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 <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/iterator/counting_iterator.hpp>
|
||||||
|
#include <boost/iterator/indirect_iterator.hpp>
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
// Example of using counting_iterator_generator
|
||||||
|
std::cout << "counting from 0 to 4:" << std::endl;
|
||||||
|
boost::counting_iterator<int> first(0), last(4);
|
||||||
|
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.
|
||||||
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
const
|
||||||
|
#endif
|
||||||
|
int N = 7;
|
||||||
|
std::vector<int> numbers;
|
||||||
|
// Fill "numbers" array with [0,N)
|
||||||
|
std::copy(
|
||||||
|
boost::make_counting_iterator(0)
|
||||||
|
, boost::make_counting_iterator(N)
|
||||||
|
, std::back_inserter(numbers));
|
||||||
|
|
||||||
|
std::vector<std::vector<int>::iterator> pointers;
|
||||||
|
|
||||||
|
// Use counting iterator to fill in the array of pointers.
|
||||||
|
// causes an ICE with MSVC6
|
||||||
|
std::copy(boost::make_counting_iterator(numbers.begin()),
|
||||||
|
boost::make_counting_iterator(numbers.end()),
|
||||||
|
std::back_inserter(pointers));
|
||||||
|
|
||||||
|
// Use indirect iterator to print out numbers by accessing
|
||||||
|
// them through the array of pointers.
|
||||||
|
std::cout << "indirectly printing out the numbers from 0 to "
|
||||||
|
<< N << std::endl;
|
||||||
|
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||||
|
boost::make_indirect_iterator(pointers.end()),
|
||||||
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
61
test/filter_iterator_example.cpp
Normal file
61
test/filter_iterator_example.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Example of using the filter iterator adaptor from
|
||||||
|
// boost/iterator_adaptors.hpp.
|
||||||
|
|
||||||
|
// (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)
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
|
|
||||||
|
struct is_positive_number {
|
||||||
|
bool operator()(int x) { return 0 < x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||||
|
const int N = sizeof(numbers_)/sizeof(int);
|
||||||
|
|
||||||
|
typedef int* base_iterator;
|
||||||
|
base_iterator numbers(numbers_);
|
||||||
|
|
||||||
|
// Example using make_filter_iterator()
|
||||||
|
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
|
||||||
|
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
|
||||||
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// Example using filter_iterator
|
||||||
|
typedef boost::filter_iterator<is_positive_number, base_iterator>
|
||||||
|
FilterIter;
|
||||||
|
|
||||||
|
is_positive_number predicate;
|
||||||
|
FilterIter filter_iter_first(predicate, numbers, numbers + N);
|
||||||
|
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
|
||||||
|
|
||||||
|
std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// Another example using make_filter_iterator()
|
||||||
|
std::copy(
|
||||||
|
boost::make_filter_iterator(
|
||||||
|
std::bind2nd(std::greater<int>(), -2)
|
||||||
|
, numbers, numbers + N)
|
||||||
|
|
||||||
|
, boost::make_filter_iterator(
|
||||||
|
std::bind2nd(std::greater<int>(), -2)
|
||||||
|
, numbers + N, numbers + N)
|
||||||
|
|
||||||
|
, std::ostream_iterator<int>(std::cout, " ")
|
||||||
|
);
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
46
test/fun_out_iter_example.cpp
Normal file
46
test/fun_out_iter_example.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// (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.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/function_output_iterator.hpp>
|
||||||
|
|
||||||
|
struct string_appender
|
||||||
|
{
|
||||||
|
string_appender(std::string& s)
|
||||||
|
: m_str(&s)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(const std::string& x) const
|
||||||
|
{
|
||||||
|
*m_str += x;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string* m_str;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
std::vector<std::string> x;
|
||||||
|
x.push_back("hello");
|
||||||
|
x.push_back(" ");
|
||||||
|
x.push_back("world");
|
||||||
|
x.push_back("!");
|
||||||
|
|
||||||
|
std::string s = "";
|
||||||
|
std::copy(x.begin(), x.end(),
|
||||||
|
boost::make_function_output_iterator(string_appender(s)));
|
||||||
|
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
59
test/indirect_iterator_example.cpp
Normal file
59
test/indirect_iterator_example.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// (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;
|
||||||
|
}
|
46
test/iterator_adaptor_examples.cpp
Normal file
46
test/iterator_adaptor_examples.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// (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 <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/pending/integer_range.hpp>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int, char*[])
|
||||||
|
{
|
||||||
|
// This is a simple example of using the transform_iterators class to
|
||||||
|
// generate iterators that multiply the value returned by dereferencing
|
||||||
|
// the iterator. In this case we are multiplying by 2.
|
||||||
|
// Would be cooler to use lambda library in this example.
|
||||||
|
|
||||||
|
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
|
|
||||||
|
typedef std::binder1st< std::multiplies<int> > Function;
|
||||||
|
|
||||||
|
typedef boost::transform_iterator<Function, int*> doubling_iterator;
|
||||||
|
|
||||||
|
doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
|
||||||
|
i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));
|
||||||
|
|
||||||
|
std::cout << "multiplying the array by 2:" << std::endl;
|
||||||
|
while (i != i_end)
|
||||||
|
std::cout << *i++ << " ";
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// Here is an example of counting from 0 to 5 using the integer_range class.
|
||||||
|
|
||||||
|
boost::integer_range<int> r(0,5);
|
||||||
|
|
||||||
|
std::cout << "counting to from 0 to 4:" << std::endl;
|
||||||
|
std::copy(r.begin(), r.end(), std::ostream_iterator<int>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
214
test/iterator_traits_test.cpp
Normal file
214
test/iterator_traits_test.cpp
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
// (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;
|
||||||
|
}
|
103
test/projection_iterator_example.cpp
Normal file
103
test/projection_iterator_example.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// (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_const_projection_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;
|
||||||
|
}
|
47
test/reverse_iterator_example.cpp
Normal file
47
test/reverse_iterator_example.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// (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 <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <boost/iterator/reverse_iterator.hpp>
|
||||||
|
#include <boost/detail/iterator.hpp>
|
||||||
|
|
||||||
|
//boost::detail::iterator_traits
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
char letters_[] = "hello world!";
|
||||||
|
const int N = sizeof(letters_)/sizeof(char) - 1;
|
||||||
|
typedef char* base_iterator;
|
||||||
|
base_iterator letters(letters_);
|
||||||
|
|
||||||
|
std::cout << "original sequence of letters:\t"
|
||||||
|
<< letters_ << std::endl;
|
||||||
|
|
||||||
|
std::sort(letters, letters + N);
|
||||||
|
|
||||||
|
// Use reverse_iterator_generator to print a sequence
|
||||||
|
// of letters in reverse order.
|
||||||
|
|
||||||
|
boost::reverse_iterator<base_iterator>
|
||||||
|
reverse_letters_first(letters + N),
|
||||||
|
reverse_letters_last(letters);
|
||||||
|
|
||||||
|
std::cout << "letters in descending order:\t";
|
||||||
|
std::copy(reverse_letters_first, reverse_letters_last,
|
||||||
|
std::ostream_iterator<char>(std::cout));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// Use make_reverse_iterator() to print the sequence
|
||||||
|
// of letters in reverse-reverse order.
|
||||||
|
|
||||||
|
std::cout << "letters in ascending order:\t";
|
||||||
|
std::copy(boost::make_reverse_iterator(reverse_letters_last),
|
||||||
|
boost::make_reverse_iterator(reverse_letters_first),
|
||||||
|
std::ostream_iterator<char>(std::cout));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
76
test/transform_iterator_example.cpp
Normal file
76
test/transform_iterator_example.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// (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 <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
|
||||||
|
// What a bummer. We can't use std::binder1st with transform iterator
|
||||||
|
// because it does not have a default constructor. Here's a version
|
||||||
|
// that does.
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template <class Operation>
|
||||||
|
class binder1st
|
||||||
|
: public std::unary_function<typename Operation::second_argument_type,
|
||||||
|
typename Operation::result_type> {
|
||||||
|
protected:
|
||||||
|
Operation op;
|
||||||
|
typename Operation::first_argument_type value;
|
||||||
|
public:
|
||||||
|
binder1st() { } // this had to be added!
|
||||||
|
binder1st(const Operation& x,
|
||||||
|
const typename Operation::first_argument_type& y)
|
||||||
|
: op(x), value(y) {}
|
||||||
|
typename Operation::result_type
|
||||||
|
operator()(const typename Operation::second_argument_type& x) const {
|
||||||
|
return op(value, x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Operation, class T>
|
||||||
|
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
|
||||||
|
typedef typename Operation::first_argument_type arg1_type;
|
||||||
|
return binder1st<Operation>(op, arg1_type(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int, char*[])
|
||||||
|
{
|
||||||
|
// This is a simple example of using the transform_iterators class to
|
||||||
|
// generate iterators that multiply the value returned by dereferencing
|
||||||
|
// the iterator. In this case we are multiplying by 2.
|
||||||
|
// Would be cooler to use lambda library in this example.
|
||||||
|
|
||||||
|
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
|
const int N = sizeof(x)/sizeof(int);
|
||||||
|
|
||||||
|
typedef boost::binder1st< std::multiplies<int> > Function;
|
||||||
|
typedef boost::transform_iterator<Function, int*> doubling_iterator;
|
||||||
|
|
||||||
|
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
|
||||||
|
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
|
||||||
|
|
||||||
|
std::cout << "multiplying the array by 2:" << std::endl;
|
||||||
|
while (i != i_end)
|
||||||
|
std::cout << *i++ << " ";
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
std::cout << "adding 4 to each element in the array:" << std::endl;
|
||||||
|
|
||||||
|
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
|
||||||
|
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
||||||
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user