[boost][range] - merge from trunk which fixes a defect in the strided range adaptor, and contains improvements to the documentation

[SVN r67454]
This commit is contained in:
Neil Groves
2010-12-26 15:13:43 +00:00
312 changed files with 5215 additions and 1461 deletions

View File

@@ -116,7 +116,7 @@ namespace boost
};
template< class P, class R, bool default_pass >
struct adjacent_filter_range
struct adjacent_filtered_range
: iterator_range< skip_iterator<
BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
P,
@@ -138,7 +138,7 @@ namespace boost
typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
public:
adjacent_filter_range( const P& p, R& r )
adjacent_filtered_range( const P& p, R& r )
: base_range(skip_iter(boost::begin(r), boost::end(r), p),
skip_iter(boost::end(r), boost::end(r), p))
{
@@ -164,37 +164,37 @@ namespace boost
};
template< class ForwardRng, class BinPredicate >
inline adjacent_filter_range<BinPredicate, ForwardRng, true>
inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
operator|( ForwardRng& r,
const adjacent_holder<BinPredicate>& f )
{
return adjacent_filter_range<BinPredicate, ForwardRng, true>( f.val, r );
return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
}
template< class ForwardRng, class BinPredicate >
inline adjacent_filter_range<BinPredicate, const ForwardRng, true>
inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
operator|( const ForwardRng& r,
const adjacent_holder<BinPredicate>& f )
{
return adjacent_filter_range<BinPredicate,
const ForwardRng, true>( f.val, r );
return adjacent_filtered_range<BinPredicate,
const ForwardRng, true>( f.val, r );
}
template< class ForwardRng, class BinPredicate >
inline adjacent_filter_range<BinPredicate, ForwardRng, false>
inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
operator|( ForwardRng& r,
const adjacent_excl_holder<BinPredicate>& f )
{
return adjacent_filter_range<BinPredicate, ForwardRng, false>( f.val, r );
return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
}
template< class ForwardRng, class BinPredicate >
inline adjacent_filter_range<BinPredicate, ForwardRng, false>
inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
operator|( const ForwardRng& r,
const adjacent_excl_holder<BinPredicate>& f )
{
return adjacent_filter_range<BinPredicate,
const ForwardRng, false>( f.val, r );
return adjacent_filtered_range<BinPredicate,
const ForwardRng, false>( f.val, r );
}
} // 'range_detail'
@@ -202,7 +202,7 @@ namespace boost
// Bring adjacent_filter_range into the boost namespace so that users of
// this library may specify the return type of the '|' operator and
// adjacent_filter()
using range_detail::adjacent_filter_range;
using range_detail::adjacent_filtered_range;
namespace adaptors
{
@@ -218,17 +218,17 @@ namespace boost
}
template<class ForwardRng, class BinPredicate>
inline adjacent_filter_range<BinPredicate, ForwardRng, true>
inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
{
return adjacent_filter_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
}
template<class ForwardRng, class BinPredicate>
inline adjacent_filter_range<BinPredicate, const ForwardRng, true>
inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
{
return adjacent_filter_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
}
} // 'adaptors'

View File

@@ -1,3 +1,13 @@
// 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/
//
#ifndef BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED

View File

@@ -20,7 +20,7 @@ namespace boost
namespace range_detail
{
template< class P, class R >
struct filter_range :
struct filtered_range :
boost::iterator_range<
boost::filter_iterator< P,
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
@@ -34,7 +34,7 @@ namespace boost
>
> base;
public:
filter_range( P p, R& r )
filtered_range( P p, R& r )
: base( make_filter_iterator( p, boost::begin(r), boost::end(r) ),
make_filter_iterator( p, boost::end(r), boost::end(r) ) )
{ }
@@ -48,19 +48,19 @@ namespace boost
};
template< class InputRng, class Predicate >
inline filter_range<Predicate, InputRng>
inline filtered_range<Predicate, InputRng>
operator|( InputRng& r,
const filter_holder<Predicate>& f )
{
return filter_range<Predicate, InputRng>( f.val, r );
return filtered_range<Predicate, InputRng>( f.val, r );
}
template< class InputRng, class Predicate >
inline filter_range<Predicate, const InputRng>
inline filtered_range<Predicate, const InputRng>
operator|( const InputRng& r,
const filter_holder<Predicate>& f )
{
return filter_range<Predicate, const InputRng>( f.val, r );
return filtered_range<Predicate, const InputRng>( f.val, r );
}
} // 'range_detail'
@@ -70,7 +70,7 @@ namespace boost
// argument dependent lookup.
// filter_range logically needs to be in the boost namespace to allow user of
// the library to define the return type for filter()
using range_detail::filter_range;
using range_detail::filtered_range;
namespace adaptors
{
@@ -82,17 +82,17 @@ namespace boost
}
template<class InputRange, class Predicate>
inline filter_range<Predicate, InputRange>
inline filtered_range<Predicate, InputRange>
filter(InputRange& rng, Predicate filter_pred)
{
return range_detail::filter_range<Predicate, InputRange>( filter_pred, rng );
return range_detail::filtered_range<Predicate, InputRange>( filter_pred, rng );
}
template<class InputRange, class Predicate>
inline filter_range<Predicate, const InputRange>
inline filtered_range<Predicate, const InputRange>
filter(const InputRange& rng, Predicate filter_pred)
{
return range_detail::filter_range<Predicate, const InputRange>( filter_pred, rng );
return range_detail::filtered_range<Predicate, const InputRange>( filter_pred, rng );
}
} // 'adaptors'

View File

@@ -19,7 +19,7 @@ namespace boost
namespace range_detail
{
template< class R >
struct indirect_range :
struct indirected_range :
public boost::iterator_range<
boost::indirect_iterator<
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
@@ -35,7 +35,7 @@ namespace boost
base;
public:
explicit indirect_range( R& r )
explicit indirected_range( R& r )
: base( r )
{ }
};
@@ -43,22 +43,22 @@ namespace boost
struct indirect_forwarder {};
template< class InputRng >
inline indirect_range<InputRng>
inline indirected_range<InputRng>
operator|( InputRng& r, indirect_forwarder )
{
return indirect_range<InputRng>( r );
return indirected_range<InputRng>( r );
}
template< class InputRng >
inline indirect_range<const InputRng>
inline indirected_range<const InputRng>
operator|( const InputRng& r, indirect_forwarder )
{
return indirect_range<const InputRng>( r );
return indirected_range<const InputRng>( r );
}
} // 'range_detail'
using range_detail::indirect_range;
using range_detail::indirected_range;
namespace adaptors
{
@@ -69,17 +69,17 @@ namespace boost
}
template<class InputRange>
inline indirect_range<InputRange>
inline indirected_range<InputRange>
indirect(InputRange& rng)
{
return indirect_range<InputRange>(rng);
return indirected_range<InputRange>(rng);
}
template<class InputRange>
inline indirect_range<const InputRange>
inline indirected_range<const InputRange>
indirect(const InputRange& rng)
{
return indirect_range<const InputRange>(rng);
return indirected_range<const InputRange>(rng);
}
} // 'adaptors'

View File

@@ -14,6 +14,7 @@
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/reference.hpp>
namespace boost
{
@@ -25,11 +26,10 @@ namespace boost
template< class Map >
struct select_first
{
typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type pair_t;
typedef const BOOST_DEDUCED_TYPENAME pair_t::first_type&
result_type;
typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type;
result_type operator()( const pair_t& r ) const
result_type operator()( argument_type r ) const
{
return r.first;
}
@@ -38,10 +38,10 @@ namespace boost
template< class Map >
struct select_second_mutable
{
typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type pair_t;
typedef BOOST_DEDUCED_TYPENAME pair_t::second_type& result_type;
typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type;
typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type;
result_type operator()( pair_t& r ) const
result_type operator()( argument_type r ) const
{
return r.second;
}
@@ -50,11 +50,10 @@ namespace boost
template< class Map >
struct select_second_const
{
typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type pair_t;
typedef const BOOST_DEDUCED_TYPENAME pair_t::second_type&
result_type;
typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type;
result_type operator()( const pair_t& r ) const
result_type operator()( argument_type r ) const
{
return r.second;
}
@@ -62,11 +61,11 @@ namespace boost
template<class StdPairRng>
class select_first_range
: public transform_range<
: public transformed_range<
select_first<StdPairRng>,
const StdPairRng>
{
typedef transform_range<select_first<StdPairRng>, const StdPairRng> base;
typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base;
public:
typedef select_first<StdPairRng> transform_fn_type;
typedef const StdPairRng source_range_type;
@@ -81,11 +80,11 @@ namespace boost
template<class StdPairRng>
class select_second_mutable_range
: public transform_range<
: public transformed_range<
select_second_mutable<StdPairRng>,
StdPairRng>
{
typedef transform_range<select_second_mutable<StdPairRng>, StdPairRng> base;
typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base;
public:
typedef select_second_mutable<StdPairRng> transform_fn_type;
typedef StdPairRng source_range_type;
@@ -100,11 +99,11 @@ namespace boost
template<class StdPairRng>
class select_second_const_range
: public transform_range<
: public transformed_range<
select_second_const<StdPairRng>,
const StdPairRng>
{
typedef transform_range<select_second_const<StdPairRng>, const StdPairRng> base;
typedef transformed_range<select_second_const<StdPairRng>, const StdPairRng> base;
public:
typedef select_second_const<StdPairRng> transform_fn_type;
typedef const StdPairRng source_range_type;
@@ -122,7 +121,7 @@ namespace boost
operator|( const StdPairRng& r, map_keys_forwarder )
{
return operator|( r,
boost::adaptors::transformed( select_first<StdPairRng>() ) );
boost::adaptors::transformed( select_first<StdPairRng>() ) );
}
template< class StdPairRng >
@@ -130,7 +129,7 @@ namespace boost
operator|( StdPairRng& r, map_values_forwarder )
{
return operator|( r,
boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
}
template< class StdPairRng >
@@ -138,7 +137,7 @@ namespace boost
operator|( const StdPairRng& r, map_values_forwarder )
{
return operator|( r,
boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
}
} // 'range_detail'

View File

@@ -47,7 +47,7 @@ namespace boost
};
template< class Pred, class R >
class replace_if_range :
class replaced_if_range :
public boost::iterator_range<
boost::transform_iterator<
replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
@@ -64,7 +64,7 @@ namespace boost
public:
typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
replace_if_range( R& r, const Pred& pred, value_type to )
replaced_if_range( R& r, const Pred& pred, value_type to )
: base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
make_transform_iterator( boost::end(r), Fn(pred, to) ) )
{ }
@@ -87,23 +87,23 @@ namespace boost
};
template< class Pred, class InputRng >
inline replace_if_range<Pred, InputRng>
inline replaced_if_range<Pred, InputRng>
operator|( InputRng& r,
const replace_if_holder<Pred, BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
{
return replace_if_range<Pred, InputRng>(r, f.pred(), f.to());
return replaced_if_range<Pred, InputRng>(r, f.pred(), f.to());
}
template< class Pred, class InputRng >
inline replace_if_range<Pred, const InputRng>
inline replaced_if_range<Pred, const InputRng>
operator|( const InputRng& r,
const replace_if_holder<Pred, BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
{
return replace_if_range<Pred, const InputRng>(r, f.pred(), f.to());
return replaced_if_range<Pred, const InputRng>(r, f.pred(), f.to());
}
} // 'range_detail'
using range_detail::replace_if_range;
using range_detail::replaced_if_range;
namespace adaptors
{
@@ -115,19 +115,19 @@ namespace boost
}
template<class Pred, class InputRange>
inline replace_if_range<Pred, InputRange>
inline replaced_if_range<Pred, InputRange>
replace_if(InputRange& rng, Pred pred,
BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
{
return range_detail::replace_if_range<Pred, InputRange>(rng, pred, to);
return range_detail::replaced_if_range<Pred, InputRange>(rng, pred, to);
}
template<class Pred, class InputRange>
inline replace_if_range<Pred, const InputRange>
inline replaced_if_range<Pred, const InputRange>
replace_if(const InputRange& rng, Pred pred,
BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
{
return range_detail::replace_if_range<Pred, const InputRange>(rng, pred, to);
return range_detail::replaced_if_range<Pred, const InputRange>(rng, pred, to);
}
} // 'adaptors'

View File

@@ -19,7 +19,7 @@ namespace boost
namespace range_detail
{
template< class R >
struct reverse_range :
struct reversed_range :
public boost::iterator_range<
boost::reverse_iterator<
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
@@ -37,7 +37,7 @@ namespace boost
public:
typedef boost::reverse_iterator<BOOST_DEDUCED_TYPENAME range_iterator<R>::type> iterator;
reverse_range( R& r )
explicit reversed_range( R& r )
: base( iterator(boost::end(r)), iterator(boost::begin(r)) )
{ }
};
@@ -45,22 +45,22 @@ namespace boost
struct reverse_forwarder {};
template< class BidirectionalRng >
inline reverse_range<BidirectionalRng>
inline reversed_range<BidirectionalRng>
operator|( BidirectionalRng& r, reverse_forwarder )
{
return reverse_range<BidirectionalRng>( r );
return reversed_range<BidirectionalRng>( r );
}
template< class BidirectionalRng >
inline reverse_range<const BidirectionalRng>
inline reversed_range<const BidirectionalRng>
operator|( const BidirectionalRng& r, reverse_forwarder )
{
return reverse_range<const BidirectionalRng>( r );
return reversed_range<const BidirectionalRng>( r );
}
} // 'range_detail'
using range_detail::reverse_range;
using range_detail::reversed_range;
namespace adaptors
{
@@ -71,17 +71,17 @@ namespace boost
}
template<class BidirectionalRange>
inline reverse_range<BidirectionalRange>
inline reversed_range<BidirectionalRange>
reverse(BidirectionalRange& rng)
{
return reverse_range<BidirectionalRange>(rng);
return reversed_range<BidirectionalRange>(rng);
}
template<class BidirectionalRange>
inline reverse_range<const BidirectionalRange>
inline reversed_range<const BidirectionalRange>
reverse(const BidirectionalRange& rng)
{
return reverse_range<const BidirectionalRange>(rng);
return reversed_range<const BidirectionalRange>(rng);
}
} // 'adaptors'

View File

@@ -27,53 +27,53 @@ namespace boost
std::size_t u;
};
template< class RandomAccessRange >
class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
{
typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
public:
template<typename Rng, typename T, typename U>
sliced_range(Rng& rng, T t, U u)
: base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
{
}
};
template< class RandomAccessRange >
class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
{
typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
public:
template<typename Rng, typename T, typename U>
sliced_range(Rng& rng, T t, U u)
: base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
{
}
};
template< class RandomAccessRange >
inline sliced_range<RandomAccessRange>
slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
{
BOOST_ASSERT( t <= u && "error in slice indices" );
template< class RandomAccessRange >
inline sliced_range<RandomAccessRange>
slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
{
BOOST_ASSERT( t <= u && "error in slice indices" );
BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
"second slice index out of bounds" );
"second slice index out of bounds" );
return sliced_range<RandomAccessRange>(rng, t, u);
}
return sliced_range<RandomAccessRange>(rng, t, u);
}
template< class RandomAccessRange >
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
{
BOOST_ASSERT( t <= u && "error in slice indices" );
BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
"second slice index out of bounds" );
template< class RandomAccessRange >
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
{
BOOST_ASSERT( t <= u && "error in slice indices" );
BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
"second slice index out of bounds" );
return sliced_range<const RandomAccessRange>(rng, t, u);
}
}
template< class RandomAccessRange >
inline sliced_range<RandomAccessRange>
operator|( RandomAccessRange& r, const sliced& f )
{
return sliced_range<RandomAccessRange>( r, f.t, f.u );
}
template< class RandomAccessRange >
inline sliced_range<RandomAccessRange>
operator|( RandomAccessRange& r, const sliced& f )
{
return sliced_range<RandomAccessRange>( r, f.t, f.u );
}
template< class RandomAccessRange >
inline sliced_range<const RandomAccessRange>
operator|( const RandomAccessRange& r, const sliced& f )
{
return sliced_range<const RandomAccessRange>( r, f.t, f.u );
}
template< class RandomAccessRange >
inline sliced_range<const RandomAccessRange>
operator|( const RandomAccessRange& r, const sliced& f )
{
return sliced_range<const RandomAccessRange>( r, f.t, f.u );
}
} // namespace adaptors
} // namespace boost

View File

@@ -16,68 +16,119 @@
#include <boost/iterator/iterator_adaptor.hpp>
#include <iterator>
#include <iostream>
namespace boost
{
namespace range_detail
{
template<typename BaseIterator>
template<class BaseIterator>
class strided_iterator
: public iterator_adaptor<
strided_iterator<BaseIterator>,
BaseIterator>
strided_iterator<BaseIterator>
, BaseIterator
>
{
friend class iterator_core_access;
typedef iterator_adaptor<strided_iterator<BaseIterator>, BaseIterator> super_t;
public:
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
strided_iterator() : m_stride() { }
strided_iterator(const strided_iterator& other)
: super_t(other), m_stride(other.m_stride) { }
explicit strided_iterator(BaseIterator base_it, difference_type stride)
: super_t(base_it), m_stride(stride) { }
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
strided_iterator()
: m_stride(), m_offset(), m_max_offset()
{
}
explicit strided_iterator(BaseIterator base_it,
difference_type stride,
difference_type offset,
difference_type max_offset)
: super_t(base_it)
, m_stride(stride)
, m_offset(offset)
, m_max_offset(max_offset)
{
}
template<class OtherIterator>
strided_iterator(const strided_iterator<OtherIterator>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0)
: super_t(other)
, m_stride(other.m_stride)
, m_offset(other.m_offset)
, m_max_offset(other.m_max_offset)
{
}
strided_iterator&
operator=(const strided_iterator& other)
{
super_t::operator=(other);
// Is the interoperation of the stride safe?
m_stride = other.m_stride;
m_offset = other.m_offset;
m_max_offset = other.m_max_offset;
return *this;
}
void increment() { std::advance(this->base_reference(), m_stride); }
void decrement() { std::advance(this->base_reference(), -m_stride); }
void advance(difference_type n) { std::advance(this->base_reference(), n * m_stride); }
void increment()
{
m_offset += m_stride;
if (m_offset <= m_max_offset)
std::advance(this->base_reference(), m_stride);
}
void decrement()
{
m_offset -= m_stride;
if (m_offset >= 0)
std::advance(this->base_reference(), -m_stride);
}
void advance(difference_type n)
{
n *= m_stride;
m_offset += n;
if (m_offset >= 0 && m_offset <= m_max_offset)
std::advance(this->base_reference(), n);
}
template<class OtherIterator>
bool equal(const strided_iterator<OtherIterator>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const
{
return m_offset == other.m_offset;
}
difference_type
distance_to(const strided_iterator& other) const
{
return std::distance(this->base_reference(), other.base_reference()) / m_stride;
return (other.m_offset - m_offset) / m_stride;
}
// Using the compiler generated copy constructor and
// and assignment operator
private:
difference_type m_stride;
difference_type m_offset;
difference_type m_max_offset;
};
template<class BaseIterator> inline
template<class BaseIterator, class Difference> inline
strided_iterator<BaseIterator>
make_strided_iterator(
const BaseIterator& first,
BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type stride)
Difference stride,
typename std::iterator_traits<BaseIterator>::difference_type offset,
typename std::iterator_traits<BaseIterator>::difference_type max_offset
)
{
return strided_iterator<BaseIterator>(first, stride);
BOOST_ASSERT( stride >= 0 );
BOOST_ASSERT( (stride == 0) || (offset % stride == 0) );
BOOST_ASSERT( (stride == 0) || (max_offset % stride == 0) );
BOOST_ASSERT( offset <= max_offset );
return strided_iterator<BaseIterator>(first, stride, offset, max_offset);
}
template< class Rng >
@@ -87,11 +138,33 @@ namespace boost
typedef range_detail::strided_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> iter_type;
typedef iterator_range<iter_type> super_t;
public:
template< typename Difference >
template<class Difference>
strided_range(Difference stride, Rng& rng)
: super_t(make_strided_iterator(boost::begin(rng), stride),
make_strided_iterator(boost::end(rng), stride))
: super_t(make_super(stride, rng))
{
BOOST_ASSERT( stride >= 0 );
}
private:
template<class Difference>
static super_t make_super(const Difference stride, Rng& rng)
{
const Difference count = boost::size(rng);
const Difference max_count = max_offset(count, stride);
return super_t(make_strided_iterator(boost::begin(rng), stride, 0, max_count),
make_strided_iterator(boost::end(rng), stride, max_count, max_count));
}
template<class Difference, class Stride>
static Difference max_offset(Difference sz, const Stride stride)
{
if (stride > 0)
{
sz += stride - 1;
sz /= stride;
sz *= stride;
}
return sz;
}
};
@@ -99,7 +172,7 @@ namespace boost
class strided_holder : public holder<Difference>
{
public:
strided_holder(Difference value) : holder<Difference>(value) {}
explicit strided_holder(Difference value) : holder<Difference>(value) {}
};
template<class Rng, class Difference>
@@ -117,32 +190,32 @@ namespace boost
}
} // namespace range_detail
using range_detail::strided_range;
namespace adaptors
{
namespace
{
const range_detail::forwarder<range_detail::strided_holder>
strided = range_detail::forwarder<range_detail::strided_holder>();
}
template<class Range, class Difference>
inline strided_range<Range>
stride(Range& rng, Difference step)
{
return strided_range<Range>(step, rng);
}
template<class Range, class Difference>
inline strided_range<const Range>
stride(const Range& rng, Difference step)
{
return strided_range<const Range>(step, rng);
}
} // namespace 'adaptors'
} // namespace 'boost'

View File

@@ -20,7 +20,7 @@ namespace boost
{
template< class R >
struct token_range :
struct tokenized_range :
public boost::iterator_range<
boost::regex_token_iterator<
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
@@ -42,7 +42,7 @@ namespace boost
public:
template< class Regex, class Submatch, class Flag >
token_range( R& r, const Regex& re, const Submatch& sub, Flag f )
tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f )
: base( regex_iter( boost::begin(r), boost::end(r),
regex_type(re), sub, f ),
regex_iter() )
@@ -90,24 +90,24 @@ namespace boost
};
template< class BidirectionalRng, class R, class S, class F >
inline token_range<BidirectionalRng>
inline tokenized_range<BidirectionalRng>
operator|( BidirectionalRng& r,
const regex_holder<R,S,F>& f )
{
return token_range<BidirectionalRng>( r, f.re, f.sub, f.f );
return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );
}
template< class BidirectionalRng, class R, class S, class F >
inline token_range<const BidirectionalRng>
inline tokenized_range<const BidirectionalRng>
operator|( const BidirectionalRng& r,
const regex_holder<R,S,F>& f )
{
return token_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
}
} // 'range_detail'
using range_detail::token_range;
using range_detail::tokenized_range;
namespace adaptors
{
@@ -118,17 +118,17 @@ namespace boost
}
template<class BidirectionalRange, class Regex, class Submatch, class Flag>
inline token_range<BidirectionalRange>
inline tokenized_range<BidirectionalRange>
tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
{
return token_range<BidirectionalRange>(rng, reg, sub, f);
return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
}
template<class BidirectionalRange, class Regex, class Submatch, class Flag>
inline token_range<const BidirectionalRange>
inline tokenized_range<const BidirectionalRange>
tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
{
return token_range<const BidirectionalRange>(rng, reg, sub, f);
return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
}
} // 'adaptors'

View File

@@ -14,6 +14,7 @@
#include <boost/range/adaptor/argument_fwd.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/utility/result_of.hpp>
namespace boost
{
@@ -21,17 +22,17 @@ namespace boost
{
template< class F, class R >
struct transform_range :
public boost::iterator_range<
struct transformed_range :
public boost::iterator_range<
boost::transform_iterator< F,
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
>
>
{
private:
typedef boost::iterator_range<
typedef boost::iterator_range<
boost::transform_iterator< F,
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
>
>
base;
@@ -39,11 +40,11 @@ namespace boost
public:
typedef F transform_fn_type;
typedef R source_range_type;
transform_range( F f, R& r )
transformed_range( F f, R& r )
: base( make_transform_iterator( boost::begin(r), f ),
make_transform_iterator( boost::end(r), f ) )
make_transform_iterator( boost::end(r), f ) )
{ }
};
@@ -53,51 +54,51 @@ namespace boost
transform_holder( T r ) : holder<T>(r)
{ }
};
template< class InputRng, class UnaryFunction >
inline transform_range<UnaryFunction,InputRng>
operator|( InputRng& r,
inline transformed_range<UnaryFunction,InputRng>
operator|( InputRng& r,
const transform_holder<UnaryFunction>& f )
{
return transform_range<UnaryFunction,InputRng>( f.val, r );
return transformed_range<UnaryFunction,InputRng>( f.val, r );
}
template< class InputRng, class UnaryFunction >
inline transform_range<UnaryFunction, const InputRng>
operator|( const InputRng& r,
inline transformed_range<UnaryFunction, const InputRng>
operator|( const InputRng& r,
const transform_holder<UnaryFunction>& f )
{
return transform_range<UnaryFunction, const InputRng>( f.val, r );
return transformed_range<UnaryFunction, const InputRng>( f.val, r );
}
} // 'range_detail'
using range_detail::transform_range;
using range_detail::transformed_range;
namespace adaptors
{
{
namespace
{
const range_detail::forwarder<range_detail::transform_holder>
transformed =
const range_detail::forwarder<range_detail::transform_holder>
transformed =
range_detail::forwarder<range_detail::transform_holder>();
}
template<class UnaryFunction, class InputRange>
inline transform_range<UnaryFunction, InputRange>
inline transformed_range<UnaryFunction, InputRange>
transform(InputRange& rng, UnaryFunction fn)
{
return transform_range<UnaryFunction, InputRange>(fn, rng);
return transformed_range<UnaryFunction, InputRange>(fn, rng);
}
template<class UnaryFunction, class InputRange>
inline transform_range<UnaryFunction, const InputRange>
inline transformed_range<UnaryFunction, const InputRange>
transform(const InputRange& rng, UnaryFunction fn)
{
return transform_range<UnaryFunction, const InputRange>(fn, rng);
return transformed_range<UnaryFunction, const InputRange>(fn, rng);
}
} // 'adaptors'
}
#endif

View File

@@ -0,0 +1,90 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. 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_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/range_reference.hpp>
#include <boost/range/range_value.hpp>
namespace boost
{
namespace range_detail
{
template<
class Value,
class CategoryOrTraversal,
class Reference,
class Difference
>
class any_range
: public iterator_range<
IteratorTypeErasure::any_iterator<
Value, CategoryOrTraversal, Reference, Difference> >
{
typedef typename IteratorTypeErasure::any_iterator<
Value, CategoryOrTraversal, Reference, Difference> iterator_t;
typedef iterator_range<iterator_t> base_t;
public:
template<class Range>
explicit any_range(Range& r) : base_t(r) {}
template<class Range>
explicit any_range(const Range& r) : base_t(r) {}
};
template<class Range>
class any_range_generator
{
public:
typedef any_range<
BOOST_DEDUCED_TYPENAME range_value<Range>::type,
BOOST_DEDUCED_TYPENAME iterator_traversal<
BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
>::type,
BOOST_DEDUCED_TYPENAME range_reference<Range>::type,
BOOST_DEDUCED_TYPENAME range_difference<Range>::type
> type;
};
class type_erased_tag {};
} // namespace range_detail
using range_detail::any_range;
namespace adaptors
{
namespace
{
const range_detail::type_erased_tag type_erased = range_detail::type_erased_tag();
}
template<class SinglePassRange>
typename range_detail::any_range_generator<SinglePassRange>::type
operator|(SinglePassRange& rng, range_detail::type_erased_tag)
{
typedef typename range_detail::any_range_generator<SinglePassRange>::type range_t;
return range_t(rng);
}
template<class SinglePassRange>
typename range_detail::any_range_generator<const SinglePassRange>::type
operator|(const SinglePassRange& rng, range_detail::type_erased_tag)
{
typedef typename range_detail::any_range_generator<const SinglePassRange>::type range_t;
return range_t(rng);
}
}
} // namespace boost
#endif // include guard

View File

@@ -32,35 +32,35 @@ namespace boost
};
template<class ForwardRng>
class unique_range : public adjacent_filter_range<unique_not_equal_to, ForwardRng, true>
class uniqued_range : public adjacent_filtered_range<unique_not_equal_to, ForwardRng, true>
{
typedef adjacent_filter_range<unique_not_equal_to, ForwardRng, true> base;
typedef adjacent_filtered_range<unique_not_equal_to, ForwardRng, true> base;
public:
explicit unique_range(ForwardRng& rng)
explicit uniqued_range(ForwardRng& rng)
: base(unique_not_equal_to(), rng)
{
}
};
template< class ForwardRng >
inline unique_range<ForwardRng>
inline uniqued_range<ForwardRng>
operator|( ForwardRng& r,
unique_forwarder )
{
return unique_range<ForwardRng>(r);
return uniqued_range<ForwardRng>(r);
}
template< class ForwardRng >
inline unique_range<const ForwardRng>
inline uniqued_range<const ForwardRng>
operator|( const ForwardRng& r,
unique_forwarder )
{
return unique_range<const ForwardRng>(r);
return uniqued_range<const ForwardRng>(r);
}
} // 'range_detail'
using range_detail::unique_range;
using range_detail::uniqued_range;
namespace adaptors
{
@@ -71,17 +71,17 @@ namespace boost
}
template<class ForwardRange>
inline unique_range<ForwardRange>
inline uniqued_range<ForwardRange>
unique(ForwardRange& rng)
{
return unique_range<ForwardRange>(rng);
return uniqued_range<ForwardRange>(rng);
}
template<class ForwardRange>
inline unique_range<const ForwardRange>
inline uniqued_range<const ForwardRange>
unique(const ForwardRange& rng)
{
return unique_range<const ForwardRange>(rng);
return uniqued_range<const ForwardRange>(rng);
}
} // 'adaptors'

View File

@@ -15,6 +15,7 @@
#include <boost/range/concepts.hpp>
#include <boost/range/detail/range_return.hpp>
#include <boost/range/value_type.hpp>
#include <iterator>
#include <algorithm>
namespace boost
@@ -22,6 +23,218 @@ namespace boost
namespace range
{
namespace range_detail
{
// Rationale: search_n is implemented rather than delegate to
// the standard library implementation because some standard
// library implementations are broken eg. MSVC.
// search_n forward iterator version
template<typename ForwardIterator, typename Integer, typename Value>
inline ForwardIterator
search_n_impl(ForwardIterator first, ForwardIterator last, Integer count,
const Value& value, std::forward_iterator_tag)
{
first = std::find(first, last, value);
while (first != last)
{
typename std::iterator_traits<ForwardIterator>::difference_type n = count;
ForwardIterator i = first;
++i;
while (i != last && n != 1 && *i==value)
{
++i;
--n;
}
if (n == 1)
return first;
if (i == last)
return last;
first = std::find(++i, last, value);
}
return last;
}
// search_n random-access iterator version
template<typename RandomAccessIterator, typename Integer, typename Value>
inline RandomAccessIterator
search_n_impl(RandomAccessIterator first, RandomAccessIterator last,
Integer count, const Value& value,
std::random_access_iterator_tag)
{
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
difference_t tail_size = last - first;
const difference_t pattern_size = count;
if (tail_size < pattern_size)
return last;
const difference_t skip_offset = pattern_size - 1;
RandomAccessIterator look_ahead = first + skip_offset;
tail_size -= pattern_size;
while (1)
{
// look_ahead here is pointing to the last element of the
// next possible match
while (!(*look_ahead == value)) // skip loop...
{
if (tail_size < pattern_size)
return last; // no match
look_ahead += pattern_size;
tail_size -= pattern_size;
}
difference_t remainder = skip_offset;
for (RandomAccessIterator back_track = look_ahead - 1;
*back_track == value; --back_track)
{
if (--remainder == 0)
{
return look_ahead - skip_offset; // matched
}
}
if (remainder > tail_size)
return last; // no match
look_ahead += remainder;
tail_size -= remainder;
}
return last;
}
// search_n for forward iterators using a binary predicate
// to determine a match
template<typename ForwardIterator, typename Integer, typename Value,
typename BinaryPredicate>
inline ForwardIterator
search_n_pred_impl(ForwardIterator first, ForwardIterator last,
Integer count, const Value& value,
BinaryPredicate pred, std::forward_iterator_tag)
{
typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
while (first != last && !static_cast<bool>(pred(*first, value)))
++first;
while (first != last)
{
difference_t n = count;
ForwardIterator i = first;
++i;
while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
{
++i;
--n;
}
if (n == 1)
return first;
if (i == last)
return last;
first = ++i;
while (first != last && !static_cast<bool>(pred(*first, value)))
++first;
}
return last;
}
// search_n for random-access iterators using a binary predicate
// to determine a match
template<typename RandomAccessIterator, typename Integer,
typename Value, typename BinaryPredicate>
inline RandomAccessIterator
search_n_pred_impl(RandomAccessIterator first, RandomAccessIterator last,
Integer count, const Value& value,
BinaryPredicate pred, std::random_access_iterator_tag)
{
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
difference_t tail_size = last - first;
const difference_t pattern_size = count;
if (tail_size < pattern_size)
return last;
const difference_t skip_offset = pattern_size - 1;
RandomAccessIterator look_ahead = first + skip_offset;
tail_size -= pattern_size;
while (1)
{
// look_ahead points to the last element of the next
// possible match
while (!static_cast<bool>(pred(*look_ahead, value))) // skip loop
{
if (tail_size < pattern_size)
return last; // no match
look_ahead += pattern_size;
tail_size -= pattern_size;
}
difference_t remainder = skip_offset;
for (RandomAccessIterator back_track = look_ahead - 1;
pred(*back_track, value); --back_track)
{
if (--remainder == 0)
return look_ahead -= skip_offset; // success
}
if (remainder > tail_size)
{
return last; // no match
}
look_ahead += remainder;
tail_size -= remainder;
}
}
template<typename ForwardIterator, typename Integer, typename Value>
inline ForwardIterator
search_n_impl(ForwardIterator first, ForwardIterator last,
Integer count, const Value& value)
{
BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<Value>));
BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<typename std::iterator_traits<ForwardIterator>::value_type>));
//BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2<typename std::iterator_traits<ForwardIterator>::value_type, Value>));
typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
if (count <= 0)
return first;
if (count == 1)
return std::find(first, last, value);
return range_detail::search_n_impl(first, last, count, value, cat_t());
}
template<typename ForwardIterator, typename Integer, typename Value,
typename BinaryPredicate>
inline ForwardIterator
search_n_pred_impl(ForwardIterator first, ForwardIterator last,
Integer count, const Value& value,
BinaryPredicate pred)
{
BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
BOOST_RANGE_CONCEPT_ASSERT((
BinaryPredicateConcept<
BinaryPredicate,
typename std::iterator_traits<ForwardIterator>::value_type,
Value>
));
typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
if (count <= 0)
return first;
if (count == 1)
{
while (first != last && !static_cast<bool>(pred(*first, value)))
++first;
return first;
}
return range_detail::search_n_pred_impl(first, last, count,
value, pred, cat_t());
}
} // namespace range_detail
/// \brief template function search
///
/// range-based version of the search std algorithm
@@ -36,7 +249,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
search_n(ForwardRange& rng, Integer count, const Value& value)
{
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
return std::search_n(boost::begin(rng),boost::end(rng), count, value);
return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
}
/// \overload
@@ -45,7 +258,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
search_n(const ForwardRange& rng, Integer count, const Value& value)
{
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
return std::search_n(boost::begin(rng), boost::end(rng), count, value);
return range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
}
/// \overload
@@ -58,7 +271,7 @@ search_n(ForwardRange& rng, Integer count, const Value& value,
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
return std::search_n(boost::begin(rng), boost::end(rng),
return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
count, value, binary_pred);
}
@@ -72,7 +285,7 @@ search_n(const ForwardRange& rng, Integer count, const Value& value,
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
return std::search_n(boost::begin(rng), boost::end(rng),
return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
count, value, binary_pred);
}
@@ -86,7 +299,7 @@ search_n(ForwardRange& rng, Integer count, const Value& value)
{
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
return range_return<ForwardRange,re>::
pack(std::search_n(boost::begin(rng),boost::end(rng),
pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
count, value),
rng);
}
@@ -99,7 +312,7 @@ search_n(const ForwardRange& rng, Integer count, const Value& value)
{
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
return range_return<const ForwardRange,re>::
pack(std::search_n(boost::begin(rng), boost::end(rng),
pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
count, value),
rng);
}
@@ -116,7 +329,8 @@ search_n(ForwardRange& rng, Integer count, const Value& value,
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
const Value&>));
return range_return<ForwardRange,re>::
pack(std::search_n(boost::begin(rng), boost::end(rng),
pack(range_detail::search_n_pred_impl(boost::begin(rng),
boost::end(rng),
count, value, pred),
rng);
}
@@ -133,7 +347,8 @@ search_n(const ForwardRange& rng, Integer count, const Value& value,
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
const Value&>));
return range_return<const ForwardRange,re>::
pack(std::search_n(boost::begin(rng), boost::end(rng),
pack(range_detail::search_n_pred_impl(boost::begin(rng),
boost::end(rng),
count, value, pred),
rng);
}

View File

@@ -84,7 +84,7 @@ namespace boost
{
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
return range_detail::transform_impl(
return boost::range_detail::transform_impl(
boost::begin(rng1), boost::end(rng1),
boost::begin(rng2), boost::end(rng2),
out, fun);

View File

@@ -1,3 +1,11 @@
// 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/
//
#ifndef BOOST_RANGE_COMBINE_HPP
#define BOOST_RANGE_COMBINE_HPP

View File

@@ -98,8 +98,9 @@ namespace boost {
// classes:
//
// The Range algorithms often do not require that the iterators are
// Assignable, but the correct standard conformant iterators
// do require the iterators to be a model of the Assignable concept.
// Assignable or default constructable, but the correct standard
// conformant iterators do require the iterators to be a model of the
// Assignable concept.
// Iterators that contains a functor that is not assignable therefore
// are not correct models of the standard iterator concepts,
// despite being adequate for most algorithms. An example of this
@@ -141,6 +142,23 @@ namespace boost {
BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
single_pass_traversal_tag
>));
BOOST_CONCEPT_USAGE(SinglePassIteratorConcept)
{
Iterator i2(++i);
boost::ignore_unused_variable_warning(i2);
Iterator i3(i++);
boost::ignore_unused_variable_warning(i3);
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r1(*i);
boost::ignore_unused_variable_warning(r1);
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r2(*i++);
boost::ignore_unused_variable_warning(r2);
}
private:
Iterator i;
#endif
};

View File

@@ -1,13 +1,11 @@
// 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)
//
// Copyright Neil Groves 2008. Use, modification and
// distribution is subject to the Boost Software Licence, 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
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED

View File

@@ -0,0 +1,62 @@
// 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/
//
#ifndef BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
#define BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
#include <boost/mpl/bool.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/range/iterator.hpp>
#include <boost/utility.hpp>
namespace boost
{
namespace range_detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(type);
template<class T, class Enabler = void>
struct has_range_iterator_impl
: boost::mpl::false_
{
};
template<class T>
struct has_range_iterator_impl<T, BOOST_DEDUCED_TYPENAME enable_if< has_type< range_mutable_iterator<T> > >::type>
: boost::mpl::true_
{
};
template<class T, class Enabler = void>
struct has_range_const_iterator_impl
: boost::mpl::false_
{
};
template<class T>
struct has_range_const_iterator_impl<T, BOOST_DEDUCED_TYPENAME enable_if< has_type< range_const_iterator<T> > >::type>
: boost::mpl::true_
{
};
} // namespace range_detail
template<class T>
struct has_range_iterator
: range_detail::has_range_iterator_impl<T>
{};
template<class T>
struct has_range_const_iterator
: range_detail::has_range_const_iterator_impl<T>
{};
} // namespace boost
#endif // include guard

View File

@@ -1,13 +1,11 @@
// 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)
//
// Copyright Neil Groves 2008. Use, modification and
// distribution is subject to the Boost Software Licence, 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
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED

View File

@@ -230,7 +230,7 @@ namespace boost
difference_type size() const
{
return m_End - m_Begin;
return std::distance(m_Begin, m_End);
}
bool empty() const
@@ -290,6 +290,20 @@ namespace boost
return *--last;
}
// pop_front() - added to model the SinglePassRangePrimitiveConcept
void pop_front()
{
BOOST_ASSERT( !empty() );
++m_Begin;
}
// pop_back() - added to model the BidirectionalRangePrimitiveConcept
void pop_back()
{
BOOST_ASSERT( !empty() );
--m_End;
}
reference operator[]( difference_type at ) const
{
BOOST_ASSERT( at >= 0 && at < size() );

1
include/boost/range/metafunctions.hpp Executable file → Normal file
View File

@@ -16,6 +16,7 @@
#endif
#include <boost/range/iterator.hpp>
#include <boost/range/has_range_iterator.hpp>
#include <boost/range/result_iterator.hpp>
#include <boost/range/reverse_iterator.hpp>
#include <boost/range/const_reverse_iterator.hpp>

View File

@@ -15,6 +15,7 @@
# pragma once
#endif
#include <boost/iterator/iterator_categories.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/difference_type.hpp>
@@ -22,13 +23,47 @@
namespace boost
{
template< class T >
inline BOOST_DEDUCED_TYPENAME range_difference<T>::type size( const T& r )
namespace range_detail
{
BOOST_ASSERT( (boost::end( r ) - boost::begin( r )) >= 0 &&
"reachability invariant broken!" );
return boost::end( r ) - boost::begin( r );
template< class SinglePassRange >
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
size_impl(const SinglePassRange& rng, boost::single_pass_traversal_tag)
{
typedef BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type diff_t;
// A compilation error here will often indicate that an algorithm
// is attempting to use boost::size(rng) for a range that is not a
// model of the RandomAccessRange Concept and does not have a
// member size() function.
// The solution to this issue is to add a range_calculate_size()
// function for the range type that will be found via ADL.
return static_cast<diff_t>(rng.size());
}
template< class SinglePassRange >
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
size_impl(const SinglePassRange& rng, boost::random_access_traversal_tag)
{
BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 &&
"reachability invariant broken!" );
return boost::end(rng) - boost::begin(rng);
}
} // namespace range_detail
template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
range_calculate_size(const SinglePassRange& rng)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type iter_t;
typedef BOOST_DEDUCED_TYPENAME iterator_traversal<iter_t>::type traversal_tag;
return range_detail::size_impl(rng, traversal_tag());
}
template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
size(const SinglePassRange& rng)
{
return range_calculate_size(rng);
}
} // namespace 'boost'