[boost][range] - merge from trunk of miscellaneous defect fixes

[SVN r72427]
This commit is contained in:
Neil Groves
2011-06-05 21:47:57 +00:00
28 changed files with 721 additions and 147 deletions

View File

@ -11,7 +11,7 @@
#include <boost/range/algorithm/copy.hpp> #include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp> #include <boost/assign.hpp>
#include <algorithm> #include <algorithm>
#include <functinoal> #include <functional>
#include <iostream> #include <iostream>
#include <vector> #include <vector>

View File

@ -41,5 +41,5 @@ int main(int argc, const char* argv[])
display_element_and_index( input | indexed(0) ); display_element_and_index( input | indexed(0) );
return 0; return 0;
] }

View File

@ -9,7 +9,7 @@
// //
#include <boost/range/adaptor/transformed.hpp> #include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp> #include <boost/range/algorithm/copy.hpp>
#include <boost/range/assign.hpp> #include <boost/assign.hpp>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <vector> #include <vector>

View File

@ -143,10 +143,6 @@ namespace boost
skip_iter(boost::end(r), boost::end(r), p)) skip_iter(boost::end(r), boost::end(r), p))
{ {
} }
private:
P m_pred;
R* m_range;
}; };
template< class T > template< class T >

View File

@ -44,24 +44,6 @@
return range_adaptor <const Range>(rng); \ return range_adaptor <const Range>(rng); \
} }
#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, adaptor_class ) \
template<typename Range> range_adaptor <Range> \
operator|(Range& rng, const adaptor_name & args) \
{ \
return range_adaptor <Range>(rng, args.arg1); \
} \
template<typename Range> range_adaptor <const Range> \
operator|(const Range& rng, const adaptor_name & args) \
{ \
return range_adaptor <Range>(rng, args.arg1); \
} \
template<typename Range, typename Arg1> \
range_adaptor<Range> \
make_##adaptor_name(Range& rng, Arg1 arg1) \
{ \
return range_adaptor<Range>(rng, arg1); \
}
#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \ #define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \
struct adaptor_name \ struct adaptor_name \
{ \ { \

43
include/boost/range/adaptor/strided.hpp Executable file → Normal file
View File

@ -176,6 +176,7 @@ namespace boost
strided_iterator() strided_iterator()
: m_first() : m_first()
, m_last() , m_last()
, m_index(0)
, m_stride() , m_stride()
{ {
} }
@ -184,6 +185,7 @@ namespace boost
: super_t(it) : super_t(it)
, m_first(first) , m_first(first)
, m_last(last) , m_last(last)
, m_index(stride ? (it - first) / stride : 0)
, m_stride(stride) , m_stride(stride)
{ {
} }
@ -194,6 +196,7 @@ namespace boost
: super_t(other.base()) : super_t(other.base())
, m_first(other.base_begin()) , m_first(other.base_begin())
, m_last(other.base_end()) , m_last(other.base_end())
, m_index(other.get_index())
, m_stride(other.get_stride()) , m_stride(other.get_stride())
{ {
} }
@ -201,44 +204,37 @@ namespace boost
base_iterator base_begin() const { return m_first; } base_iterator base_begin() const { return m_first; }
base_iterator base_end() const { return m_last; } base_iterator base_end() const { return m_last; }
difference_type get_stride() const { return m_stride; } difference_type get_stride() const { return m_stride; }
difference_type get_index() const { return m_index; }
private: private:
void increment() void increment()
{ {
base_iterator& it = this->base_reference(); m_index += m_stride;
if ((m_last - it) > m_stride) if (m_index < (m_last - m_first))
it += m_stride; this->base_reference() = m_first + m_index;
else else
it = m_last; this->base_reference() = m_last;
} }
void decrement() void decrement()
{ {
base_iterator& it = this->base_reference(); m_index -= m_stride;
if ((it - m_first) > m_stride) if (m_index >= 0)
it -= m_stride; this->base_reference() = m_first + m_index;
else else
it = m_first; this->base_reference() = m_first;
} }
void advance(difference_type offset) void advance(difference_type offset)
{ {
base_iterator& it = this->base_reference();
offset *= m_stride; offset *= m_stride;
if (offset >= 0) m_index += offset;
{ if (m_index < 0)
if ((m_last - it) > offset) this->base_reference() = m_first;
it += offset; else if (m_index > (m_last - m_first))
else this->base_reference() = m_last;
it = m_last;
}
else else
{ this->base_reference() = m_first + m_index;
if ((m_first - it) > offset)
it += offset;
else
it = m_first;
}
} }
template<class OtherIterator> template<class OtherIterator>
@ -252,12 +248,13 @@ namespace boost
bool equal(const strided_iterator& other) const bool equal(const strided_iterator& other) const
{ {
return other.base() == this->base(); return this->base() == other.base();
} }
private: private:
base_iterator m_first; base_iterator m_first;
base_iterator m_last; base_iterator m_last;
difference_type m_index;
difference_type m_stride; difference_type m_stride;
}; };

4
include/boost/range/adaptor/transformed.hpp Executable file → Normal file
View File

@ -42,8 +42,8 @@ namespace boost
typedef R source_range_type; typedef R source_range_type;
transformed_range( F f, R& r ) transformed_range( F f, R& r )
: base( make_transform_iterator( boost::begin(r), f ), : base( boost::make_transform_iterator( boost::begin(r), f ),
make_transform_iterator( boost::end(r), f ) ) boost::make_transform_iterator( boost::end(r), f ) )
{ } { }
}; };

66
include/boost/range/algorithm/for_each.hpp Executable file → Normal file
View File

@ -13,13 +13,53 @@
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>
#include <algorithm> #include <algorithm>
#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
#include <xutility>
#endif
namespace boost namespace boost
{ {
namespace range namespace range
{ {
#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
namespace for_each_detail
{
template<typename Iterator, typename UnaryFunction>
inline UnaryFunction
for_each_impl(Iterator first, Iterator last, UnaryFunction fun,
typename enable_if<
is_reference_wrapper<UnaryFunction>,
void
>::type* = 0)
{
typedef typename std::_Get_unchecked_type<Iterator>::type
unchecked_iterator;
unchecked_iterator unchecked_last = std::_Unchecked(last);
for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first)
fun.get()(*unchecked_first);
return fun;
}
template<typename Iterator, typename UnaryFunction>
inline UnaryFunction
for_each_impl(Iterator first, Iterator last, UnaryFunction fn,
typename disable_if<
is_reference_wrapper<UnaryFunction>,
void
>::type* = 0)
{
return std::for_each<Iterator, UnaryFunction>(first, last, fn);
}
}
#endif
/// \brief template function for_each /// \brief template function for_each
/// ///
/// range-based version of the for_each std algorithm /// range-based version of the for_each std algorithm
@ -30,7 +70,18 @@ template< class SinglePassRange, class UnaryFunction >
inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun) inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
return std::for_each(boost::begin(rng),boost::end(rng),fun);
#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
return for_each_detail::for_each_impl<
typename range_iterator<SinglePassRange>::type,
UnaryFunction
>(boost::begin(rng), boost::end(rng), fun);
#else
return std::for_each<
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type,
UnaryFunction
>(boost::begin(rng),boost::end(rng),fun);
#endif
} }
/// \overload /// \overload
@ -38,7 +89,18 @@ template< class SinglePassRange, class UnaryFunction >
inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun) inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
return std::for_each(boost::begin(rng), boost::end(rng), fun);
#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
return for_each_detail::for_each_impl<
typename range_iterator<const SinglePassRange>::type,
UnaryFunction
>(boost::begin(rng), boost::end(rng), fun);
#else
return std::for_each<
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type,
UnaryFunction
>(boost::begin(rng), boost::end(rng), fun);
#endif
} }
} // namespace range } // namespace range

42
include/boost/range/algorithm_ext/is_sorted.hpp Executable file → Normal file
View File

@ -1,3 +1,4 @@
// Copyright Bryce Lelbach 2010
// Copyright Neil Groves 2009. Use, modification and // Copyright Neil Groves 2009. Use, modification and
// distribution is subject to the Boost Software License, Version // distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@ -14,45 +15,26 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <boost/detail/is_sorted.hpp>
#include <algorithm> #include <algorithm>
namespace boost namespace boost
{ {
namespace range_detail
{
template<class ForwardIterator>
inline bool is_sorted(ForwardIterator first, ForwardIterator last)
{
for (ForwardIterator next = first; first != last && ++next != last; ++first)
if (*next < *first)
return false;
return true;
}
template<class ForwardIterator, class BinaryPredicate>
inline bool is_sorted(ForwardIterator first, ForwardIterator last, BinaryPredicate pred)
{
for (ForwardIterator next = first; first != last && ++next != last; ++first)
if (pred(*next, *first))
return false;
return true;
}
}
namespace range namespace range
{ {
/// \brief template function count /// \brief template function is_sorted
/// ///
/// range-based version of the count std algorithm /// range-based version of the is_sorted std algorithm
/// ///
/// \pre SinglePassRange is a model of the SinglePassRangeConcept /// \pre SinglePassRange is a model of the SinglePassRangeConcept
template<class SinglePassRange> template<class SinglePassRange>
inline bool is_sorted(const SinglePassRange& rng) inline bool is_sorted(const SinglePassRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>)); BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept<BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type>)); BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept<BOOST_DEDUCED_TYPENAME
return range_detail::is_sorted(boost::begin(rng), boost::end(rng)); range_value<const SinglePassRange>::type>));
return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng));
} }
/// \overload /// \overload
@ -60,12 +42,16 @@ template<class SinglePassRange, class BinaryPredicate>
inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred) inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>)); BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate, BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type, BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type>)); BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
return range_detail::is_sorted(boost::begin(rng), boost::end(rng), pred); BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type,
BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type>));
return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred);
} }
} // namespace range } // namespace range
using range::is_sorted;
using range::is_sorted;
} // namespace boost } // namespace boost
#endif // include guard #endif // include guard

View File

@ -15,6 +15,7 @@
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_adaptor.hpp>
#include <boost/range/detail/any_iterator.hpp> #include <boost/range/detail/any_iterator.hpp>
#include <boost/range/concepts.hpp>
#include <boost/range/reference.hpp> #include <boost/range/reference.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <boost/range/iterator_range_core.hpp> #include <boost/range/iterator_range_core.hpp>

View File

@ -5,6 +5,9 @@
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
// Acknowledgements:
// aschoedl supplied a fix to supply the level of interoperability I had
// originally intended, but failed to implement.
// //
// For more information, see http://www.boost.org/libs/range/ // For more information, see http://www.boost.org/libs/range/
// //
@ -19,12 +22,12 @@ namespace boost
{ {
template<class IteratorTraversalTag1, class IteratorTraversalTag2> template<class IteratorTraversalTag1, class IteratorTraversalTag2>
struct demote_iterator_traversal_tag struct inner_demote_iterator_traversal_tag
{ {
}; };
#define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \ #define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \
template<> struct demote_iterator_traversal_tag< Tag1 , Tag2 > \ template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \
{ \ { \
typedef ResultTag type; \ typedef ResultTag type; \
}; };
@ -73,6 +76,15 @@ BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal
#undef BOOST_DEMOTE_TRAVERSAL_TAG #undef BOOST_DEMOTE_TRAVERSAL_TAG
template<class IteratorTraversalTag1, class IteratorTraversalTag2>
struct demote_iterator_traversal_tag
: inner_demote_iterator_traversal_tag<
typename boost::detail::pure_traversal_tag< IteratorTraversalTag1 >::type,
typename boost::detail::pure_traversal_tag< IteratorTraversalTag2 >::type
>
{
};
} // namespace range_detail } // namespace range_detail
} // namespace boost } // namespace boost

4
include/boost/range/detail/detail_str.hpp Executable file → Normal file
View File

@ -134,8 +134,8 @@ namespace boost
#include <boost/range/detail/begin.hpp> #include <boost/range/detail/begin.hpp>
#include <boost/range/detail/end.hpp> #include <boost/range/detail/end.hpp>
#include <boost/range/detail/size_type> #include <boost/range/detail/size_type.hpp>
#include <boost/range/detail/value_type> #include <boost/range/detail/value_type.hpp>
#include <boost/range/detail/common.hpp> #include <boost/range/detail/common.hpp>
namespace boost namespace boost

View File

@ -5,6 +5,9 @@
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
// Acknowledgements:
// aschoedl contributed an improvement to the determination
// of the Reference type parameter.
// //
// For more information, see http://www.boost.org/libs/range/ // For more information, see http://www.boost.org/libs/range/
// //
@ -120,7 +123,32 @@ private:
template<typename Iterator1 template<typename Iterator1
, typename Iterator2 , typename Iterator2
, typename ValueType = typename iterator_value<Iterator1>::type , typename ValueType = typename iterator_value<Iterator1>::type
, typename Reference = typename iterator_reference<Iterator1>::type // find least demanding, commonly supported reference type, in the order &, const&, and by-value:
, typename Reference = typename mpl::if_c<
!is_reference<typename iterator_reference<Iterator1>::type>::value
|| !is_reference<typename iterator_reference<Iterator2>::type>::value,
typename remove_const<
typename remove_reference<
typename iterator_reference<Iterator1>::type
>::type
>::type,
typename mpl::if_c<
is_const<
typename remove_reference<
typename iterator_reference<Iterator1>::type
>::type
>::value
|| is_const<
typename remove_reference<
typename iterator_reference<Iterator2>::type
>::type
>::value,
typename add_const<
typename iterator_reference<Iterator2>::type
>::type,
typename iterator_reference<Iterator1>::type
>::type
>::type
, typename Traversal = typename demote_iterator_traversal_tag< , typename Traversal = typename demote_iterator_traversal_tag<
typename iterator_traversal<Iterator1>::type typename iterator_traversal<Iterator1>::type
, typename iterator_traversal<Iterator2>::type>::type , typename iterator_traversal<Iterator2>::type>::type

View File

@ -19,7 +19,7 @@ namespace boost
{ {
namespace range_detail namespace range_detail
{ {
BOOST_MPL_HAS_XXX_TRAIT_DEF(type); BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
template<class T, class Enabler = void> template<class T, class Enabler = void>
struct has_range_iterator_impl struct has_range_iterator_impl

View File

@ -124,13 +124,11 @@ namespace boost
typedef typename base_t::difference_type difference_type; typedef typename base_t::difference_type difference_type;
typedef typename base_t::reference reference; typedef typename base_t::reference reference;
integer_iterator_with_step(value_type first, value_type step, difference_type step_size) integer_iterator_with_step(value_type first, difference_type step, value_type step_size)
: m_first(first) : m_first(first)
, m_step(step) , m_step(step)
, m_step_size(step_size) , m_step_size(step_size)
{ {
BOOST_ASSERT( step >= 0 );
BOOST_ASSERT( step_size != 0 );
} }
private: private:
@ -213,16 +211,18 @@ namespace boost
{ {
BOOST_ASSERT( step_size != 0 ); BOOST_ASSERT( step_size != 0 );
BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) ); BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) );
typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t; typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t;
const std::ptrdiff_t last_step const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size);
= (static_cast<std::ptrdiff_t>(last) - static_cast<std::ptrdiff_t>(first)) const Integer l = step_size >= 0 ? last : first;
/ (static_cast<std::ptrdiff_t>(step_size)); const Integer f = step_size >= 0 ? first : last;
const std::ptrdiff_t num_steps = (l + ((l-f) % sz) - f) / sz;
BOOST_ASSERT(num_steps >= 0);
return strided_integer_range<Integer>( return strided_integer_range<Integer>(
iterator_t(first, 0, step_size), iterator_t(first, 0, step_size),
iterator_t(first, last_step, step_size)); iterator_t(first, num_steps, step_size));
} }
} // namespace boost } // namespace boost

View File

@ -53,13 +53,13 @@ namespace boost
template< class ForwardRange > template< class ForwardRange >
static IteratorT adl_begin( ForwardRange& r ) static IteratorT adl_begin( ForwardRange& r )
{ {
return IteratorT( boost::begin( r ) ); return static_cast<IteratorT>( boost::begin( r ) );
} }
template< class ForwardRange > template< class ForwardRange >
static IteratorT adl_end( ForwardRange& r ) static IteratorT adl_end( ForwardRange& r )
{ {
return IteratorT( boost::end( r ) ); return static_cast<IteratorT>( boost::end( r ) );
} }
}; };
@ -71,6 +71,24 @@ namespace boost
boost::begin(r), boost::begin(r),
boost::end(r) ); boost::end(r) );
} }
template< class Left, class Right >
inline bool greater_than( const Left& l, const Right& r )
{
return less_than(r,l);
}
template< class Left, class Right >
inline bool less_or_equal_than( const Left& l, const Right& r )
{
return !iterator_range_detail::less_than(r,l);
}
template< class Left, class Right >
inline bool greater_or_equal_than( const Left& l, const Right& r )
{
return !iterator_range_detail::less_than(l,r);
}
// This version is maintained since it is used in other boost libraries // This version is maintained since it is used in other boost libraries
// such as Boost.Assign // such as Boost.Assign
@ -271,6 +289,21 @@ namespace boost
{ {
return iterator_range_detail::less_than( *this, r ); return iterator_range_detail::less_than( *this, r );
} }
bool operator>( const iterator_range& r ) const
{
return iterator_range_detail::greater_than( *this, r );
}
bool operator<=( const iterator_range& r ) const
{
return iterator_range_detail::less_or_equal_than( *this, r );
}
bool operator>=( const iterator_range& r ) const
{
return iterator_range_detail::greater_or_equal_than( *this, r );
}
#endif #endif
@ -370,6 +403,27 @@ namespace boost
{ {
return iterator_range_detail::less_than( l, r ); return iterator_range_detail::less_than( l, r );
} }
template< class IteratorT, class ForwardRange >
inline bool operator<=( const ForwardRange& l,
const iterator_range<IteratorT>& r )
{
return iterator_range_detail::less_or_equal_than( l, r );
}
template< class IteratorT, class ForwardRange >
inline bool operator>( const ForwardRange& l,
const iterator_range<IteratorT>& r )
{
return iterator_range_detail::greater_than( l, r );
}
template< class IteratorT, class ForwardRange >
inline bool operator>=( const ForwardRange& l,
const iterator_range<IteratorT>& r )
{
return iterator_range_detail::greater_or_equal_than( l, r );
}
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
#else #else
@ -416,6 +470,48 @@ namespace boost
{ {
return iterator_range_detail::less_than( l, r ); return iterator_range_detail::less_than( l, r );
} }
template< class Iterator1T, class Iterator2T >
inline bool operator<=( const iterator_range<Iterator1T>& l,
const iterator_range<Iterator2T>& r )
{
return iterator_range_detail::less_or_equal_than( l, r );
}
template< class IteratorT, class ForwardRange >
inline bool operator<=( const iterator_range<IteratorT>& l,
const ForwardRange& r )
{
return iterator_range_detail::less_or_equal_than( l, r );
}
template< class Iterator1T, class Iterator2T >
inline bool operator>( const iterator_range<Iterator1T>& l,
const iterator_range<Iterator2T>& r )
{
return iterator_range_detail::greater_than( l, r );
}
template< class IteratorT, class ForwardRange >
inline bool operator>( const iterator_range<IteratorT>& l,
const ForwardRange& r )
{
return iterator_range_detail::greater_than( l, r );
}
template< class Iterator1T, class Iterator2T >
inline bool operator>=( const iterator_range<Iterator1T>& l,
const iterator_range<Iterator2T>& r )
{
return iterator_range_detail::greater_or_equal_than( l, r );
}
template< class IteratorT, class ForwardRange >
inline bool operator>=( const iterator_range<IteratorT>& l,
const ForwardRange& r )
{
return iterator_range_detail::greater_or_equal_than( l, r );
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

View File

@ -36,6 +36,9 @@ public:
} // namespace range_detail } // namespace range_detail
namespace range
{
template<class SinglePassRange1, class SinglePassRange2> template<class SinglePassRange1, class SinglePassRange2>
class joined_range class joined_range
: public range_detail::joined_type<SinglePassRange1, SinglePassRange2>::type : public range_detail::joined_type<SinglePassRange1, SinglePassRange2>::type
@ -78,6 +81,11 @@ join(SinglePassRange1& r1, SinglePassRange2& r2)
return joined_range<SinglePassRange1, SinglePassRange2>(r1, r2); return joined_range<SinglePassRange1, SinglePassRange2>(r1, r2);
} }
} // namespace range
using ::boost::range::joined_range;
using ::boost::range::join;
} // namespace boost } // namespace boost
#endif // include guard #endif // include guard

View File

@ -12,12 +12,13 @@
#ifndef BOOST_RANGE_SUB_RANGE_HPP #ifndef BOOST_RANGE_SUB_RANGE_HPP
#define BOOST_RANGE_SUB_RANGE_HPP #define BOOST_RANGE_SUB_RANGE_HPP
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable : 4996 ) #pragma warning( disable : 4996 )
#endif #endif
#include <boost/detail/workaround.hpp>
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
@ -30,9 +31,9 @@
namespace boost namespace boost
{ {
template< class ForwardRange > template< class ForwardRange >
class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type > class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
{ {
typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t; typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
typedef iterator_range< iterator_t > base; typedef iterator_range< iterator_t > base;
@ -53,40 +54,40 @@ namespace boost
reference >::type const_reference; reference >::type const_reference;
public: public:
sub_range() : base() sub_range() : base()
{ }
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
sub_range( const sub_range& r )
: base( static_cast<const base&>( r ) )
{ } { }
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
sub_range( const sub_range& r )
: base( static_cast<const base&>( r ) )
{ }
#endif #endif
template< class ForwardRange2 > template< class ForwardRange2 >
sub_range( ForwardRange2& r ) : sub_range( ForwardRange2& r ) :
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
base( impl::adl_begin( r ), impl::adl_end( r ) )
#else
base( r )
#endif
{ }
template< class ForwardRange2 >
sub_range( const ForwardRange2& r ) :
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 ) #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
base( impl::adl_begin( r ), impl::adl_end( r ) ) base( impl::adl_begin( r ), impl::adl_end( r ) )
#else #else
base( r ) base( r )
#endif #endif
{ }
template< class ForwardRange2 >
sub_range( const ForwardRange2& r ) :
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
base( impl::adl_begin( r ), impl::adl_end( r ) )
#else
base( r )
#endif
{ } { }
template< class Iter > template< class Iter >
sub_range( Iter first, Iter last ) : sub_range( Iter first, Iter last ) :
base( first, last ) base( first, last )
{ } { }
template< class ForwardRange2 > template< class ForwardRange2 >
sub_range& operator=( ForwardRange2& r ) sub_range& operator=( ForwardRange2& r )
{ {
@ -99,23 +100,23 @@ namespace boost
{ {
base::operator=( r ); base::operator=( r );
return *this; return *this;
} }
sub_range& operator=( const sub_range& r ) sub_range& operator=( const sub_range& r )
{ {
base::operator=( static_cast<const base&>(r) ); base::operator=( static_cast<const base&>(r) );
return *this; return *this;
} }
public: public:
iterator begin() { return base::begin(); } iterator begin() { return base::begin(); }
const_iterator begin() const { return base::begin(); } const_iterator begin() const { return base::begin(); }
iterator end() { return base::end(); } iterator end() { return base::end(); }
const_iterator end() const { return base::end(); } const_iterator end() const { return base::end(); }
difference_type size() const { return base::size(); } difference_type size() const { return base::size(); }
public: // convenience public: // convenience
reference front() reference front()
{ {
@ -173,7 +174,7 @@ namespace boost
} // namespace 'boost' } // namespace 'boost'
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#pragma warning( pop ) #pragma warning( pop )
#endif #endif

View File

@ -31,6 +31,22 @@ rule range-test ( name : includes * )
} }
test-suite range : test-suite range :
[ compile ../doc/reference/adaptors/examples/adjacent_filtered.cpp : : example_adjacent_filtered ]
[ compile ../doc/reference/adaptors/examples/copied.cpp : : example_copied ]
[ compile ../doc/reference/adaptors/examples/filtered.cpp : : example_filtered ]
[ compile ../doc/reference/adaptors/examples/indexed.cpp : : example_indexed ]
[ compile ../doc/reference/adaptors/examples/indirected.cpp : : example_indirected ]
[ compile ../doc/reference/adaptors/examples/map_keys.cpp : : example_map_keys ]
[ compile ../doc/reference/adaptors/examples/map_values.cpp : : example_map_values ]
[ compile ../doc/reference/adaptors/examples/replaced.cpp : : example_replaced ]
[ compile ../doc/reference/adaptors/examples/replaced_if.cpp : : example_replaced_if ]
[ compile ../doc/reference/adaptors/examples/reversed.cpp : : example_reversed ]
[ compile ../doc/reference/adaptors/examples/sliced.cpp : : example_sliced ]
[ compile ../doc/reference/adaptors/examples/strided.cpp : : example_strided ]
[ compile ../doc/reference/adaptors/examples/tokenized.cpp : : example_tokenized ]
[ compile ../doc/reference/adaptors/examples/transformed.cpp : : example_transformed ]
[ compile ../doc/reference/adaptors/examples/uniqued.cpp : : example_uniqued ]
[ compile-fail compile_fail/iterator_range1.cpp ]
[ range-test adaptor_test/adjacent_filtered ] [ range-test adaptor_test/adjacent_filtered ]
[ range-test adaptor_test/copied ] [ range-test adaptor_test/copied ]
[ range-test adaptor_test/filtered ] [ range-test adaptor_test/filtered ]
@ -155,5 +171,9 @@ test-suite range :
[ range-test std_container ] [ range-test std_container ]
[ range-test string ] [ range-test string ]
[ range-test sub_range ] [ range-test sub_range ]
[ range-test ticket_5486 ]
[ range-test ticket_5544_terminate_irange ]
[ range-test ticket_5547 ]
[ range-test ticket_5556_is_sorted_namespace ]
; ;

View File

@ -250,6 +250,38 @@ namespace boost
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
output.begin(), output.end() ); output.begin(), output.end() );
} }
template<typename Range>
void strided_test_ticket_5236_check_bidirectional(const Range& rng)
{
BOOST_CHECK_EQUAL( boost::distance(rng), 1 );
BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), boost::prior(boost::end(rng))), 0 );
}
template<typename Range>
void strided_test_ticket_5236_check(const Range& rng)
{
strided_test_ticket_5236_check_bidirectional(rng);
typename boost::range_iterator<const Range>::type it = boost::end(rng);
it = it - 1;
BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), it), 0 );
}
void strided_test_ticket_5236()
{
std::vector<int> v;
v.push_back(1);
strided_test_ticket_5236_check( v | boost::adaptors::strided(2) );
// Ensure that there is consistency between the random-access implementation
// and the bidirectional.
std::list<int> l;
l.push_back(1);
strided_test_ticket_5236_check_bidirectional( l | boost::adaptors::strided(2) );
}
} }
} }
@ -262,6 +294,7 @@ init_unit_test_suite(int argc, char* argv[])
test->add( BOOST_TEST_CASE( &boost::strided_test ) ); test->add( BOOST_TEST_CASE( &boost::strided_test ) );
test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) ); test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) );
test->add( BOOST_TEST_CASE( &boost::strided_test_traversal ) ); test->add( BOOST_TEST_CASE( &boost::strided_test_traversal ) );
test->add( BOOST_TEST_CASE( &boost::strided_test_ticket_5236 ) );
return test; return test;
} }

View File

@ -0,0 +1,21 @@
// Boost.Range library
//
// Copyright Neil Groves 2011. 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/iterator_range_core.hpp>
namespace iterator_range_test_detail
{
void check_iterator_range_doesnt_convert_pointers()
{
double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
boost::iterator_range<float*> rng = boost::make_iterator_range(source);
}
}

View File

@ -14,7 +14,6 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <iostream>
#include <vector> #include <vector>
namespace boost namespace boost
@ -35,27 +34,38 @@ namespace boost
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
reference.begin(), reference.end() ); reference.begin(), reference.end() );
} }
template<typename Integer>
std::ptrdiff_t test_irange_calculate_num_steps(Integer first, Integer last, int step)
{
const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step >= 0 ? step : -step);
const std::ptrdiff_t l = static_cast<std::ptrdiff_t>(step >= 0 ? last : first);
const std::ptrdiff_t f = static_cast<std::ptrdiff_t>(step >= 0 ? first : last);
return (l + ((l-f) % sz) - f) / sz;
}
// Test an integer range with a runtime specified step size. // Test an integer range with a runtime specified step size.
template<typename Integer> template<typename Integer, typename IntegerInput>
void test_irange_impl(Integer first, Integer last, int step) void test_irange_impl(IntegerInput first, IntegerInput last, int step)
{ {
BOOST_ASSERT( step != 0 ); BOOST_ASSERT( step != 0 );
// Skip tests that have negative values if the type is
// unsigned
if ((static_cast<IntegerInput>(static_cast<Integer>(first)) != first)
|| (static_cast<IntegerInput>(static_cast<Integer>(last)) != last))
return;
std::vector<Integer> reference; std::vector<Integer> reference;
if (step > 0)
{ const std::ptrdiff_t num_steps = test_irange_calculate_num_steps(first, last, step);
for (Integer i = first; i < last; i += step) Integer current_value = first;
reference.push_back(i); for (std::ptrdiff_t i = 0; i < num_steps; ++i, current_value += step)
} reference.push_back(current_value);
else
{
for (Integer i = first; i > last; i += step)
reference.push_back(i);
}
std::vector<Integer> test; std::vector<Integer> test;
boost::push_back(test, boost::irange(first, last, step)); boost::push_back(test, boost::irange(first, last, step));
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
reference.begin(), reference.end() ); reference.begin(), reference.end() );
} }
@ -81,7 +91,6 @@ namespace boost
void test_irange(int first, int last, int step_size) void test_irange(int first, int last, int step_size)
{ {
BOOST_ASSERT( step_size != 0 ); BOOST_ASSERT( step_size != 0 );
BOOST_ASSERT( (last - first) % step_size == 0 );
test_irange_impl<signed char>(first, last, step_size); test_irange_impl<signed char>(first, last, step_size);
test_irange_impl<unsigned char>(first, last, step_size); test_irange_impl<unsigned char>(first, last, step_size);
test_irange_impl<signed short>(first, last, step_size); test_irange_impl<signed short>(first, last, step_size);
@ -114,8 +123,27 @@ namespace boost
test_irange(10, 0, -1); test_irange(10, 0, -1);
test_irange(0, 2, 2); test_irange(0, 2, 2);
test_irange(2, 0, -2); test_irange(2, 0, -2);
test_irange(0, 9, 2);
test_irange(9, 0, -2);
test_irange(-9, 0, 2);
test_irange(-9, 9, 2);
test_irange(9, -9, -2);
test_irange(10, 20, 5); test_irange(10, 20, 5);
test_irange(20, 10, -5); test_irange(20, 10, -5);
test_irange(0, 0, 3);
test_irange(0, 1, 3);
test_irange(0, 2, 3);
test_irange(0, 3, 3);
test_irange(0, 4, 3);
test_irange(0, 10, 3);
test_irange(0, 0, -3);
test_irange(0, -1, -3);
test_irange(0, -2, -3);
test_irange(0, -3, -3);
test_irange(0, -4, -3);
test_irange(0, -10, -3);
} }
} // namespace boost } // namespace boost

View File

@ -24,6 +24,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector>
void check_reference_type(); void check_reference_type();
@ -102,17 +103,136 @@ void check_iterator_range()
check_reference_type(); check_reference_type();
} }
namespace iterator_range_test_detail
{
struct less
{
template< class Left, class Right >
bool operator()(const Left& l, const Right& r) const
{
return l < r;
}
};
struct greater
{
template< class Left, class Right >
bool operator()(const Left& l, const Right& r) const
{
return l > r;
}
};
struct less_or_equal
{
template< class Left, class Right >
bool operator()(const Left& l, const Right& r) const
{
return l <= r;
}
};
struct greater_or_equal
{
template< class Left, class Right >
bool operator()(const Left& l, const Right& r) const
{
return l >= r;
}
};
struct equal_to
{
template< class Left, class Right >
bool operator()(const Left& l, const Right& r) const
{
return l == r;
}
};
struct not_equal_to
{
template< class Left, class Right >
bool operator()(const Left& l, const Right& r) const
{
return l != r;
}
};
template< class Pred >
void check_iterator_range_operators_impl(Pred pred)
{
std::vector<std::string> vals;
vals.push_back(std::string());
vals.push_back("a");
vals.push_back("b");
vals.push_back("z");
vals.push_back("ab");
vals.push_back("ba");
vals.push_back("abc");
vals.push_back("cba");
vals.push_back("aa");
vals.push_back("aaa");
vals.push_back("aab");
vals.push_back("bba");
typedef std::string::const_iterator citer;
typedef boost::iterator_range<citer> iter_range;
typedef std::vector<std::string>::const_iterator value_const_iterator;
value_const_iterator first_val = vals.begin();
value_const_iterator last_val = vals.end();
for (value_const_iterator left_it = first_val; left_it != last_val; ++left_it)
{
const std::string& leftValue = *left_it;
for (value_const_iterator right_it = first_val; right_it != last_val; ++right_it)
{
const std::string& rightValue = *right_it;
iter_range left = boost::make_iterator_range(leftValue);
iter_range right = boost::make_iterator_range(rightValue);
const bool reference = pred(leftValue, rightValue);
BOOST_CHECK_EQUAL( pred(left, right), reference );
BOOST_CHECK_EQUAL( pred(left, rightValue), reference );
BOOST_CHECK_EQUAL( pred(leftValue, right), reference );
}
}
}
void check_iterator_range_from_array()
{
double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
boost::iterator_range<double*> rng = boost::make_iterator_range(source);
BOOST_CHECK_EQUAL_COLLECTIONS( rng.begin(), rng.end(),
source, source + 6 );
}
} // namespace iterator_range_test_detail
template<typename Pred>
inline void check_iterator_range_operator()
{
iterator_range_test_detail::check_iterator_range_operators_impl(
Pred());
}
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
{ {
boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_iterator_range ) ); test->add(BOOST_TEST_CASE(&check_iterator_range));
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::less>));
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::less_or_equal>));
test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater>));
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::not_equal_to>));
return test; return test;
} }
// //
// //
// Check that constness is propgated correct from // Check that constness is propgated correct from

View File

@ -371,7 +371,7 @@ namespace boost
Container reference(cont); Container reference(cont);
Container test(cont); Container test(cont);
iterator_t range_result = policy.test_iter(test); iterator_t range_result = policy.test_iter(test);
iterator_t reference_it = policy.reference(reference); iterator_t reference_it = policy.reference(reference);
@ -391,7 +391,8 @@ namespace boost
Container reference(cont); Container reference(cont);
Container test_cont(cont); Container test_cont(cont);
range_return_t range_result = test_range_t()(policy, test_cont); test_range_t test_range_fn;
range_return_t range_result = test_range_fn(policy, test_cont);
iterator_t reference_it = policy.reference(reference); iterator_t reference_it = policy.reference(reference);
check_results<result_type>::test(test_cont, reference, check_results<result_type>::test(test_cont, reference,

56
test/ticket_5486.cpp Normal file
View File

@ -0,0 +1,56 @@
// Boost.Range library
//
// Copyright Neil Groves 2011. 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/adjacent_filtered.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <functional>
#include <vector>
namespace boost
{
namespace
{
class TestTicket5486Pred
: public std::binary_function<int,int,bool>
{
public:
explicit TestTicket5486Pred(int x) {}
bool operator()(int,int) const { return true; }
private:
TestTicket5486Pred();
};
// Ticket 5486 - pertained to predicates erroneous
// requiring default construction
void test_ticket_5486()
{
std::vector<int> v;
boost::push_back(v, v | boost::adaptors::adjacent_filtered(TestTicket5486Pred(1)));
BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(),
v.begin(), v.end() );
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.ticket_5486" );
test->add( BOOST_TEST_CASE( &boost::test_ticket_5486 ) );
return test;
}

View File

@ -0,0 +1,47 @@
// Boost.Range library
//
// Copyright Neil Groves 2011. 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/irange.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
namespace boost
{
namespace
{
void test_irange_termination()
{
std::vector<int> reference;
for (int i = 0; i < 9; i += 2)
reference.push_back(i);
std::vector<int> actual;
boost::push_back(actual, boost::irange(0,9,2));
BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin(), actual.end(),
reference.begin(), reference.end());
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.ticket_5544" );
test->add( BOOST_TEST_CASE( &boost::test_irange_termination ) );
return test;
}

42
test/ticket_5547.cpp Normal file
View File

@ -0,0 +1,42 @@
// Boost.Range library
//
// Copyright Neil Groves 2011. 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/algorithm/string/join.hpp>
#include <boost/range/join.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
namespace boost
{
namespace
{
// Ticket 5547 - boost::join ambiguous with algorithm::join
void test_ticket_5547()
{
std::vector<int> x;
boost::range::join(x,x);
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.ticket_5547" );
test->add( BOOST_TEST_CASE( &boost::test_ticket_5547 ) );
return test;
}

View File

@ -0,0 +1,37 @@
// Boost.Range library
//
// Copyright Neil Groves 2011. 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/
//
// Embarrasingly, the mere inclusion of these headers in this order was
// enough to trigger the defect.
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace boost
{
namespace
{
void test_ticket_5556() {}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.ticket_5556" );
test->add( BOOST_TEST_CASE( &boost::test_ticket_5556 ) );
return test;
}