blob: 754fba652b2f870ed48afbd6ca1f301995470a7f [file] [log] [blame]
// Boost.Range library
//
// Copyright Neil Groves 2010. 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)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range/adaptor/type_erased.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
namespace boost_range_test
{
namespace type_erased_example
{
// The client interface from an OO perspective merely requires a sequence
// of integers that can be forward traversed
typedef boost::any_range<
int
, boost::forward_traversal_tag
, int
, std::ptrdiff_t
> integer_range;
namespace server
{
void display_integers(const integer_range& rng)
{
boost::copy(rng,
std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl;
}
}
namespace client
{
void run()
{
using namespace boost::assign;
using namespace boost::adaptors;
// Under most conditions one would simply use an appropriate
// any_range as a function parameter. The type_erased adaptor
// is often superfluous. However because the type_erased
// adaptor is applied to a range, we can use default template
// arguments that are generated in conjunction with the
// range type to which we are applying the adaptor.
std::vector<int> input;
input += 1,2,3,4,5;
// Note that this call is to a non-template function
server::display_integers(input);
std::list<int> input2;
input2 += 6,7,8,9,10;
// Note that this call is to the same non-tempate function
server::display_integers(input2);
input2.clear();
input2 += 11,12,13,14,15;
// Calling using the adaptor looks like this:
// Notice that here I have a type_erased that would be a
// bidirectional_traversal_tag, but this is convertible
// to the forward_traversal_tag equivalent hence this
// works.
server::display_integers(input2 | type_erased<>());
// However we may simply wish to define an adaptor that
// takes a range and makes it into an appropriate
// forward_traversal any_range...
typedef boost::adaptors::type_erased<
boost::use_default
, boost::forward_traversal_tag
> type_erased_forward;
// This adaptor can turn other containers with different
// value_types and reference_types into the appropriate
// any_range.
server::display_integers(input2 | type_erased_forward());
}
}
} // namespace type_erased_example
} // namespace boost_range_test
} // anonymous namespace
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_example" );
test->add( BOOST_TEST_CASE( &boost_range_test::type_erased_example::client::run) );
return test;
}