forked from boostorg/range
Merge branch 'develop'
This commit is contained in:
@ -63,6 +63,8 @@
|
|||||||
[def __counting_range__ [link range.reference.ranges.counting_range `counting_range`]]
|
[def __counting_range__ [link range.reference.ranges.counting_range `counting_range`]]
|
||||||
[def __irange__ [link range.reference.ranges.irange `irange`]]
|
[def __irange__ [link range.reference.ranges.irange `irange`]]
|
||||||
[def __istream_range__ [link range.reference.ranges.istream_range `istream_range`]]
|
[def __istream_range__ [link range.reference.ranges.istream_range `istream_range`]]
|
||||||
|
[def __combine__ [link range.reference.utilities.combine `combine`]]
|
||||||
|
[def __separated__ [link range.reference.utilities.separated `separated`]]
|
||||||
[def __join__ [link range.reference.utilities.join `join`]]
|
[def __join__ [link range.reference.utilities.join `join`]]
|
||||||
|
|
||||||
[def __range_adaptors__ [link range.reference.adaptors Range adaptors]]
|
[def __range_adaptors__ [link range.reference.adaptors Range adaptors]]
|
||||||
|
@ -10,6 +10,7 @@ Having an abstraction that encapsulates a pair of iterators is very useful. The
|
|||||||
* Class `iterator_range`
|
* Class `iterator_range`
|
||||||
* Class `sub_range`
|
* Class `sub_range`
|
||||||
* Function `combine`
|
* Function `combine`
|
||||||
|
* Function `separated`
|
||||||
* Function `join`
|
* Function `join`
|
||||||
|
|
||||||
The `iterator_range` class is templated on an __forward_traversal_iterator__ and should be used whenever fairly general code is needed. The `sub_range` class is templated on an __forward_range__ and it is less general, but a bit easier to use since its template argument is easier to specify. The biggest difference is, however, that a `sub_range` can propagate constness because it knows what a corresponding `const_iterator` is.
|
The `iterator_range` class is templated on an __forward_traversal_iterator__ and should be used whenever fairly general code is needed. The `sub_range` class is templated on an __forward_range__ and it is less general, but a bit easier to use since its template argument is easier to specify. The biggest difference is, however, that a `sub_range` can propagate constness because it knows what a corresponding `const_iterator` is.
|
||||||
@ -132,6 +133,12 @@ namespace boost
|
|||||||
make_iterator_range( ForwardTraversalIterator Begin,
|
make_iterator_range( ForwardTraversalIterator Begin,
|
||||||
ForwardTraversalIterator End );
|
ForwardTraversalIterator End );
|
||||||
|
|
||||||
|
// Make an iterator_range [first, boost::next(first, n) )
|
||||||
|
template< class ForwardTraversalIterator, class Integer >
|
||||||
|
iterator_range< ForwardTraversalIterator >
|
||||||
|
make_iterator_range_n( ForwardTraversalIterator first, Integer n );
|
||||||
|
|
||||||
|
|
||||||
template< class ForwardRange >
|
template< class ForwardRange >
|
||||||
iterator_range< typename range_iterator<ForwardRange>::type >
|
iterator_range< typename range_iterator<ForwardRange>::type >
|
||||||
make_iterator_range( ForwardRange& r );
|
make_iterator_range( ForwardRange& r );
|
||||||
@ -398,6 +405,55 @@ For the mutable version:
|
|||||||
The expression `join(irange(0,5), irange(5,10))` would evaluate to a range representing an integer range `[0,10)`
|
The expression `join(irange(0,5), irange(5,10))` would evaluate to a range representing an integer range `[0,10)`
|
||||||
|
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section:separated Function separated]
|
||||||
|
|
||||||
|
The separated function allows output streaming a range while writing a separator
|
||||||
|
between each element.
|
||||||
|
|
||||||
|
[h4 Synopsis]
|
||||||
|
|
||||||
|
``
|
||||||
|
template<typename Iterator, typename Separator>
|
||||||
|
class output_stream_writer
|
||||||
|
{
|
||||||
|
// ... unspecified
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Char, typename Traits>
|
||||||
|
std::basic_ostream<Char,Traits>& operator<<(
|
||||||
|
std::basic_ostream<Char,Traits>& out,
|
||||||
|
const output_stream_writer<Iterator, Separator>& writer);
|
||||||
|
|
||||||
|
template<typename Range, typename Separator>
|
||||||
|
boost::range::output_stream_writer<
|
||||||
|
typename boost::range_iterator<const Range>::type,
|
||||||
|
Separator
|
||||||
|
> separated(const Range& rng, Separator separator);
|
||||||
|
``
|
||||||
|
|
||||||
|
[h4 Example]
|
||||||
|
|
||||||
|
``
|
||||||
|
#include <boost/range/separated.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
int main(int, const char*[])
|
||||||
|
{
|
||||||
|
std::vector<int> v;
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
v.push_back(v);
|
||||||
|
|
||||||
|
std::cout << '{' << boost::range::separated(v, ',') << '}' << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
``
|
||||||
|
|
||||||
|
Produces the output: `{0,1,2,3,4}`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@ -41,20 +41,32 @@ namespace boost
|
|||||||
typedef F transform_fn_type;
|
typedef F transform_fn_type;
|
||||||
typedef R source_range_type;
|
typedef R source_range_type;
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
transformed_range( F f, R& r )
|
transformed_range( F f, R& r )
|
||||||
: base( boost::make_transform_iterator( boost::begin(r), f ),
|
: base( boost::make_transform_iterator( boost::begin(r), f ),
|
||||||
boost::make_transform_iterator( boost::end(r), f ) )
|
boost::make_transform_iterator( boost::end(r), f ) )
|
||||||
|
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
transformed_range(F&& f, R&& r)
|
||||||
|
: base(typename base::iterator(boost::begin(r), std::forward(f),
|
||||||
|
typename base::iterator(boost::end(r), std::forward(f))))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template< class T >
|
template< class T >
|
||||||
struct transform_holder : holder<T>
|
struct transform_holder : holder<T>
|
||||||
{
|
{
|
||||||
transform_holder( T r ) : holder<T>(r)
|
transform_holder( T r ) : holder<T>(r)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
template< class InputRng, class UnaryFunction >
|
template< class InputRng, class UnaryFunction >
|
||||||
inline transformed_range<UnaryFunction,InputRng>
|
inline transformed_range<UnaryFunction,InputRng>
|
||||||
operator|( InputRng& r,
|
operator|( InputRng& r,
|
||||||
@ -70,6 +82,16 @@ namespace boost
|
|||||||
{
|
{
|
||||||
return transformed_range<UnaryFunction, const InputRng>( f.val, r );
|
return transformed_range<UnaryFunction, const InputRng>( f.val, r );
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
template<class InputRng, class UnaryFunction>
|
||||||
|
inline transformed_range<UnaryFunction,InputRng>
|
||||||
|
operator|(InputRng&& r,
|
||||||
|
transform_holder<UnaryFunction>&& f)
|
||||||
|
{
|
||||||
|
return transformed_range<UnaryFunction, InputRng>(
|
||||||
|
f.val, std::forward(r));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // 'range_detail'
|
} // 'range_detail'
|
||||||
|
|
||||||
@ -84,6 +106,7 @@ namespace boost
|
|||||||
range_detail::forwarder<range_detail::transform_holder>();
|
range_detail::forwarder<range_detail::transform_holder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
template<class UnaryFunction, class InputRange>
|
template<class UnaryFunction, class InputRange>
|
||||||
inline transformed_range<UnaryFunction, InputRange>
|
inline transformed_range<UnaryFunction, InputRange>
|
||||||
transform(InputRange& rng, UnaryFunction fn)
|
transform(InputRange& rng, UnaryFunction fn)
|
||||||
@ -97,6 +120,16 @@ namespace boost
|
|||||||
{
|
{
|
||||||
return transformed_range<UnaryFunction, const InputRange>(fn, rng);
|
return transformed_range<UnaryFunction, const InputRange>(fn, rng);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
template<typename UnaryFunction, typename InputRange>
|
||||||
|
inline transformed_range<UnaryFunction, InputRange>
|
||||||
|
transform(InputRange&& rng, UnaryFunction&& fn)
|
||||||
|
{
|
||||||
|
return transformed_range<UnaryFunction, InputRange>(
|
||||||
|
std::forward(fn), std::forward(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
} // 'adaptors'
|
} // 'adaptors'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -285,8 +285,8 @@ namespace boost {
|
|||||||
iterator i1 = boost::begin(*m_range);
|
iterator i1 = boost::begin(*m_range);
|
||||||
iterator i2 = boost::end(*m_range);
|
iterator i2 = boost::end(*m_range);
|
||||||
|
|
||||||
ignore_unused_variable_warning(i1);
|
boost::ignore_unused_variable_warning(i1);
|
||||||
ignore_unused_variable_warning(i2);
|
boost::ignore_unused_variable_warning(i2);
|
||||||
|
|
||||||
const_constraints(*m_range);
|
const_constraints(*m_range);
|
||||||
}
|
}
|
||||||
@ -297,8 +297,8 @@ namespace boost {
|
|||||||
const_iterator ci1 = boost::begin(const_range);
|
const_iterator ci1 = boost::begin(const_range);
|
||||||
const_iterator ci2 = boost::end(const_range);
|
const_iterator ci2 = boost::end(const_range);
|
||||||
|
|
||||||
ignore_unused_variable_warning(ci1);
|
boost::ignore_unused_variable_warning(ci1);
|
||||||
ignore_unused_variable_warning(ci2);
|
boost::ignore_unused_variable_warning(ci2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rationale:
|
// Rationale:
|
||||||
|
@ -651,6 +651,13 @@ public:
|
|||||||
return iterator_range<IteratorT>( Begin, End );
|
return iterator_range<IteratorT>( Begin, End );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename IteratorT, typename IntegerT>
|
||||||
|
inline iterator_range<IteratorT>
|
||||||
|
make_iterator_range_n(IteratorT first, IntegerT n)
|
||||||
|
{
|
||||||
|
return iterator_range<IteratorT>(first, boost::next(first, n));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
|
||||||
template< typename Range >
|
template< typename Range >
|
||||||
|
94
include/boost/range/separated.hpp
Normal file
94
include/boost/range/separated.hpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2014.
|
||||||
|
// 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/
|
||||||
|
//
|
||||||
|
#ifndef BOOST_RANGE_SEPARATED_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_SEPARATED_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Iter, typename Separator>
|
||||||
|
class output_stream_writer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
output_stream_writer(Iter first, Iter last, Separator separator)
|
||||||
|
: m_first(first)
|
||||||
|
, m_last(last)
|
||||||
|
, m_separator(separator)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OStream>
|
||||||
|
void write(OStream& out) const
|
||||||
|
{
|
||||||
|
write_impl(out, m_first, m_last, m_separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename OStream>
|
||||||
|
static void write_impl(
|
||||||
|
OStream& out, Iter first, Iter last, Separator separator)
|
||||||
|
{
|
||||||
|
if (first != last)
|
||||||
|
{
|
||||||
|
out << *first;
|
||||||
|
for (++first; first != last; ++first)
|
||||||
|
{
|
||||||
|
out << separator << *first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iter m_first;
|
||||||
|
Iter m_last;
|
||||||
|
Separator m_separator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Char, typename Traits, typename Iter, typename Separator>
|
||||||
|
std::basic_ostream<Char, Traits>&
|
||||||
|
operator<<(
|
||||||
|
std::basic_ostream<Char, Traits>& out,
|
||||||
|
const output_stream_writer<Iter, Separator>& writer)
|
||||||
|
{
|
||||||
|
writer.write(out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Range, typename Separator>
|
||||||
|
inline range_detail::output_stream_writer<
|
||||||
|
typename range_iterator<const Range>::type,
|
||||||
|
Separator
|
||||||
|
>
|
||||||
|
separated(const Range& rng, Separator separator)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const Range>));
|
||||||
|
return range_detail::output_stream_writer<
|
||||||
|
typename range_iterator<const Range>::type,
|
||||||
|
Separator
|
||||||
|
>(boost::begin(rng), boost::end(rng), separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
@ -179,6 +179,7 @@ test-suite range :
|
|||||||
[ range-test reverse_iterator ]
|
[ range-test reverse_iterator ]
|
||||||
[ range-test reverse_result_iterator ]
|
[ range-test reverse_result_iterator ]
|
||||||
[ range-test reversible_range ]
|
[ range-test reversible_range ]
|
||||||
|
[ range-test separated ]
|
||||||
[ range-test size_type ]
|
[ range-test size_type ]
|
||||||
[ range-test std_container ]
|
[ range-test std_container ]
|
||||||
[ range-test string ]
|
[ range-test string ]
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
#include <boost/range/algorithm_ext.hpp>
|
#include <boost/range/algorithm_ext.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -92,6 +93,29 @@ namespace boost
|
|||||||
transformed_test_impl< std::set< int > >();
|
transformed_test_impl< std::set< int > >();
|
||||||
transformed_test_impl< std::multiset< int > >();
|
transformed_test_impl< std::multiset< int > >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct foo_bind
|
||||||
|
{
|
||||||
|
int foo() const { return 7; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void transformed_bind()
|
||||||
|
{
|
||||||
|
using namespace boost::adaptors;
|
||||||
|
|
||||||
|
std::vector<foo_bind> input(5);
|
||||||
|
std::vector<int> output;
|
||||||
|
boost::range::push_back(
|
||||||
|
output,
|
||||||
|
input | transformed(boost::bind(&foo_bind::foo, _1)));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(output.size(), input.size());
|
||||||
|
|
||||||
|
std::vector<int> reference_output(5, 7);
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
output.begin(), output.end(),
|
||||||
|
reference_output.begin(), reference_output.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +125,8 @@ init_unit_test_suite(int argc, char* argv[])
|
|||||||
boost::unit_test::test_suite* test
|
boost::unit_test::test_suite* test
|
||||||
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
|
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
|
||||||
|
|
||||||
test->add( BOOST_TEST_CASE( &boost::transformed_test ) );
|
test->add(BOOST_TEST_CASE(&boost::transformed_test));
|
||||||
|
test->add(BOOST_TEST_CASE(&boost::transformed_bind));
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,30 @@ namespace iterator_range_test_detail
|
|||||||
BOOST_CHECK_EQUAL_COLLECTIONS( rng.begin(), rng.end(),
|
BOOST_CHECK_EQUAL_COLLECTIONS( rng.begin(), rng.end(),
|
||||||
source, source + 6 );
|
source, source + 6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_make_iterator_range_n()
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> input;
|
||||||
|
for (uint32_t i = 0; i < 10u; ++i)
|
||||||
|
input.push_back(i);
|
||||||
|
|
||||||
|
boost::iterator_range<std::vector<uint32_t>::iterator> rng =
|
||||||
|
boost::make_iterator_range_n(boost::begin(input), 8u);
|
||||||
|
|
||||||
|
BOOST_CHECK(rng.begin() == input.begin());
|
||||||
|
BOOST_CHECK(rng.end() == input.begin() + 8);
|
||||||
|
BOOST_CHECK_EQUAL(rng.size(), 8u);
|
||||||
|
|
||||||
|
const std::vector<uint32_t>& cinput = input;
|
||||||
|
|
||||||
|
boost::iterator_range<std::vector<uint32_t>::const_iterator> crng =
|
||||||
|
boost::make_iterator_range_n(boost::begin(cinput), 8u);
|
||||||
|
|
||||||
|
BOOST_CHECK(crng.begin() == cinput.begin());
|
||||||
|
BOOST_CHECK(crng.end() == cinput.begin() + 8);
|
||||||
|
BOOST_CHECK_EQUAL(crng.size(), 8u);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace iterator_range_test_detail
|
} // namespace iterator_range_test_detail
|
||||||
|
|
||||||
template<typename Pred>
|
template<typename Pred>
|
||||||
@ -234,6 +257,7 @@ boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
|||||||
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater_or_equal>));
|
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater_or_equal>));
|
||||||
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::equal_to>));
|
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::equal_to>));
|
||||||
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::not_equal_to>));
|
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::not_equal_to>));
|
||||||
|
test->add(BOOST_TEST_CASE(&iterator_range_test_detail::check_make_iterator_range_n));
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
107
test/separated.cpp
Normal file
107
test/separated.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2014. 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/separated.hpp>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/test/test_tools.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test_separated1()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
for (boost::int32_t i = 0; i < 10; ++i)
|
||||||
|
v.push_back(i);
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << '{' << boost::range::separated(v, ',') << '}';
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(out.str(), "{0,1,2,3,4,5,6,7,8,9}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_separated2()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
v.push_back(3);
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << '{' << boost::range::separated(v, ',') << '}';
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(out.str(), "{3}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_separated3()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << '{' << boost::range::separated(v, ',') << '}';
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(out.str(), "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_separated4()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
for (boost::int32_t i = 0; i < 5; ++i)
|
||||||
|
v.push_back(i);
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << '{' << boost::range::separated(v, "::") << '}';
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(out.str(), "{0::1::2::3::4}");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udt_separator
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Char, typename Traits>
|
||||||
|
inline std::basic_ostream<Char,Traits>&
|
||||||
|
operator<<(std::basic_ostream<Char,Traits>& out, udt_separator)
|
||||||
|
{
|
||||||
|
return out << "[sep]";
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_separated5()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
for (boost::int32_t i = 0; i < 5; ++i)
|
||||||
|
v.push_back(i);
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << '{' << boost::range::separated(v, udt_separator()) << '}';
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(out.str(), "{0[sep]1[sep]2[sep]3[sep]4}");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
} // namespace boost_range_test
|
||||||
|
|
||||||
|
boost::unit_test::test_suite* init_unit_test_suite(int, char*[] )
|
||||||
|
{
|
||||||
|
boost::unit_test::test_suite* test =
|
||||||
|
BOOST_TEST_SUITE( "Boost.Range separated test suite" );
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_separated1));
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_separated2));
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_separated3));
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_separated4));
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_separated5));
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
Reference in New Issue
Block a user