forked from boostorg/range
[boost][range] - Update to relax preconditions for the strided adaptor, and numerous fixes to inspection report issues.
[SVN r67419]
This commit is contained in:
@ -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
|
#ifndef BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
|
||||||
#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
|
#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -27,53 +27,53 @@ namespace boost
|
|||||||
std::size_t u;
|
std::size_t u;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< class RandomAccessRange >
|
template< class RandomAccessRange >
|
||||||
class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
|
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;
|
typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
|
||||||
public:
|
public:
|
||||||
template<typename Rng, typename T, typename U>
|
template<typename Rng, typename T, typename U>
|
||||||
sliced_range(Rng& rng, T t, U u)
|
sliced_range(Rng& rng, T t, U u)
|
||||||
: base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
|
: base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template< class RandomAccessRange >
|
template< class RandomAccessRange >
|
||||||
inline sliced_range<RandomAccessRange>
|
inline sliced_range<RandomAccessRange>
|
||||||
slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
|
slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( t <= u && "error in slice indices" );
|
BOOST_ASSERT( t <= u && "error in slice indices" );
|
||||||
BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
|
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 >
|
template< class RandomAccessRange >
|
||||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
|
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
|
||||||
slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
|
slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( t <= u && "error in slice indices" );
|
BOOST_ASSERT( t <= u && "error in slice indices" );
|
||||||
BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
|
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<const RandomAccessRange>(rng, t, u);
|
return sliced_range<const RandomAccessRange>(rng, t, u);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class RandomAccessRange >
|
template< class RandomAccessRange >
|
||||||
inline sliced_range<RandomAccessRange>
|
inline sliced_range<RandomAccessRange>
|
||||||
operator|( RandomAccessRange& r, const sliced& f )
|
operator|( RandomAccessRange& r, const sliced& f )
|
||||||
{
|
{
|
||||||
return sliced_range<RandomAccessRange>( r, f.t, f.u );
|
return sliced_range<RandomAccessRange>( r, f.t, f.u );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class RandomAccessRange >
|
template< class RandomAccessRange >
|
||||||
inline sliced_range<const RandomAccessRange>
|
inline sliced_range<const RandomAccessRange>
|
||||||
operator|( const RandomAccessRange& r, const sliced& f )
|
operator|( const RandomAccessRange& r, const sliced& f )
|
||||||
{
|
{
|
||||||
return sliced_range<const RandomAccessRange>( r, f.t, f.u );
|
return sliced_range<const RandomAccessRange>( r, f.t, f.u );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace adaptors
|
} // namespace adaptors
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
@ -30,34 +30,34 @@ namespace boost
|
|||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
typedef iterator_adaptor<strided_iterator<BaseIterator>, BaseIterator> super_t;
|
typedef iterator_adaptor<strided_iterator<BaseIterator>, BaseIterator> super_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
|
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
|
||||||
|
|
||||||
strided_iterator() : m_stride() { }
|
strided_iterator() : m_stride() { }
|
||||||
|
|
||||||
strided_iterator(const strided_iterator& other)
|
strided_iterator(const strided_iterator& other)
|
||||||
: super_t(other), m_stride(other.m_stride) { }
|
: super_t(other), m_stride(other.m_stride) { }
|
||||||
|
|
||||||
explicit strided_iterator(BaseIterator base_it, difference_type stride)
|
explicit strided_iterator(BaseIterator base_it, difference_type stride)
|
||||||
: super_t(base_it), m_stride(stride) { }
|
: super_t(base_it), m_stride(stride) { }
|
||||||
|
|
||||||
strided_iterator&
|
strided_iterator&
|
||||||
operator=(const strided_iterator& other)
|
operator=(const strided_iterator& other)
|
||||||
{
|
{
|
||||||
super_t::operator=(other);
|
super_t::operator=(other);
|
||||||
|
|
||||||
// Is the interoperation of the stride safe?
|
// Is the interoperation of the stride safe?
|
||||||
m_stride = other.m_stride;
|
m_stride = other.m_stride;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment() { std::advance(this->base_reference(), m_stride); }
|
void increment() { std::advance(this->base_reference(), m_stride); }
|
||||||
|
|
||||||
void decrement() { 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 advance(difference_type n) { std::advance(this->base_reference(), n * m_stride); }
|
||||||
|
|
||||||
difference_type
|
difference_type
|
||||||
distance_to(const strided_iterator& other) const
|
distance_to(const strided_iterator& other) const
|
||||||
{
|
{
|
||||||
@ -66,11 +66,11 @@ namespace boost
|
|||||||
|
|
||||||
// Using the compiler generated copy constructor and
|
// Using the compiler generated copy constructor and
|
||||||
// and assignment operator
|
// and assignment operator
|
||||||
|
|
||||||
private:
|
private:
|
||||||
difference_type m_stride;
|
difference_type m_stride;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class BaseIterator> inline
|
template<class BaseIterator> inline
|
||||||
strided_iterator<BaseIterator>
|
strided_iterator<BaseIterator>
|
||||||
make_strided_iterator(
|
make_strided_iterator(
|
||||||
@ -89,9 +89,31 @@ namespace boost
|
|||||||
public:
|
public:
|
||||||
template< typename Difference >
|
template< typename Difference >
|
||||||
strided_range(Difference stride, Rng& rng)
|
strided_range(Difference stride, Rng& rng)
|
||||||
: super_t(make_strided_iterator(boost::begin(rng), stride),
|
: super_t(make_first(rng, stride), make_last(rng, stride))
|
||||||
make_strided_iterator(boost::end(rng), stride))
|
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT( stride >= 0 );
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
template<typename Difference>
|
||||||
|
static iter_type make_first(Rng& rng, Difference stride)
|
||||||
|
{
|
||||||
|
return make_strided_iterator(boost::begin(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Difference>
|
||||||
|
static iter_type make_last(Rng& rng, Difference stride)
|
||||||
|
{
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type raw_iter_t;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_difference<Rng>::type diff_t;
|
||||||
|
|
||||||
|
if (stride > 0)
|
||||||
|
{
|
||||||
|
raw_iter_t it = boost::end(rng);
|
||||||
|
const diff_t count = boost::size(rng);
|
||||||
|
std::advance(it, -(count % stride));
|
||||||
|
return iter_type(it, stride);
|
||||||
|
}
|
||||||
|
return make_strided_iterator(boost::end(rng), stride);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,7 +121,7 @@ namespace boost
|
|||||||
class strided_holder : public holder<Difference>
|
class strided_holder : public holder<Difference>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
strided_holder(Difference value) : holder<Difference>(value) {}
|
explicit strided_holder(Difference value) : holder<Difference>(value) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Rng, class Difference>
|
template<class Rng, class Difference>
|
||||||
@ -117,32 +139,32 @@ namespace boost
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace range_detail
|
} // namespace range_detail
|
||||||
|
|
||||||
using range_detail::strided_range;
|
using range_detail::strided_range;
|
||||||
|
|
||||||
namespace adaptors
|
namespace adaptors
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const range_detail::forwarder<range_detail::strided_holder>
|
const range_detail::forwarder<range_detail::strided_holder>
|
||||||
strided = range_detail::forwarder<range_detail::strided_holder>();
|
strided = range_detail::forwarder<range_detail::strided_holder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Range, class Difference>
|
template<class Range, class Difference>
|
||||||
inline strided_range<Range>
|
inline strided_range<Range>
|
||||||
stride(Range& rng, Difference step)
|
stride(Range& rng, Difference step)
|
||||||
{
|
{
|
||||||
return strided_range<Range>(step, rng);
|
return strided_range<Range>(step, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Range, class Difference>
|
template<class Range, class Difference>
|
||||||
inline strided_range<const Range>
|
inline strided_range<const Range>
|
||||||
stride(const Range& rng, Difference step)
|
stride(const Range& rng, Difference step)
|
||||||
{
|
{
|
||||||
return strided_range<const Range>(step, rng);
|
return strided_range<const Range>(step, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace 'adaptors'
|
} // namespace 'adaptors'
|
||||||
} // namespace 'boost'
|
} // namespace 'boost'
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <boost/range/adaptor/argument_fwd.hpp>
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/utility/result_of.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -21,17 +22,17 @@ namespace boost
|
|||||||
{
|
{
|
||||||
|
|
||||||
template< class F, class R >
|
template< class F, class R >
|
||||||
struct transform_range :
|
struct transform_range :
|
||||||
public boost::iterator_range<
|
public boost::iterator_range<
|
||||||
boost::transform_iterator< F,
|
boost::transform_iterator< F,
|
||||||
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef boost::iterator_range<
|
typedef boost::iterator_range<
|
||||||
boost::transform_iterator< F,
|
boost::transform_iterator< F,
|
||||||
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
base;
|
base;
|
||||||
@ -39,11 +40,11 @@ namespace boost
|
|||||||
public:
|
public:
|
||||||
typedef F transform_fn_type;
|
typedef F transform_fn_type;
|
||||||
typedef R source_range_type;
|
typedef R source_range_type;
|
||||||
|
|
||||||
transform_range( F f, R& r )
|
transform_range( F f, R& r )
|
||||||
: base( make_transform_iterator( boost::begin(r), f ),
|
: base( make_transform_iterator( boost::begin(r), f ),
|
||||||
make_transform_iterator( boost::end(r), f ) )
|
make_transform_iterator( boost::end(r), f ) )
|
||||||
|
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,43 +54,43 @@ namespace boost
|
|||||||
transform_holder( T r ) : holder<T>(r)
|
transform_holder( T r ) : holder<T>(r)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
template< class InputRng, class UnaryFunction >
|
template< class InputRng, class UnaryFunction >
|
||||||
inline transform_range<UnaryFunction,InputRng>
|
inline transform_range<UnaryFunction,InputRng>
|
||||||
operator|( InputRng& r,
|
operator|( InputRng& r,
|
||||||
const transform_holder<UnaryFunction>& f )
|
const transform_holder<UnaryFunction>& f )
|
||||||
{
|
{
|
||||||
return transform_range<UnaryFunction,InputRng>( f.val, r );
|
return transform_range<UnaryFunction,InputRng>( f.val, r );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class InputRng, class UnaryFunction >
|
template< class InputRng, class UnaryFunction >
|
||||||
inline transform_range<UnaryFunction, const InputRng>
|
inline transform_range<UnaryFunction, const InputRng>
|
||||||
operator|( const InputRng& r,
|
operator|( const InputRng& r,
|
||||||
const transform_holder<UnaryFunction>& f )
|
const transform_holder<UnaryFunction>& f )
|
||||||
{
|
{
|
||||||
return transform_range<UnaryFunction, const InputRng>( f.val, r );
|
return transform_range<UnaryFunction, const InputRng>( f.val, r );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // 'range_detail'
|
} // 'range_detail'
|
||||||
|
|
||||||
using range_detail::transform_range;
|
using range_detail::transform_range;
|
||||||
|
|
||||||
namespace adaptors
|
namespace adaptors
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const range_detail::forwarder<range_detail::transform_holder>
|
const range_detail::forwarder<range_detail::transform_holder>
|
||||||
transformed =
|
transformed =
|
||||||
range_detail::forwarder<range_detail::transform_holder>();
|
range_detail::forwarder<range_detail::transform_holder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class UnaryFunction, class InputRange>
|
template<class UnaryFunction, class InputRange>
|
||||||
inline transform_range<UnaryFunction, InputRange>
|
inline transform_range<UnaryFunction, InputRange>
|
||||||
transform(InputRange& rng, UnaryFunction fn)
|
transform(InputRange& rng, UnaryFunction fn)
|
||||||
{
|
{
|
||||||
return transform_range<UnaryFunction, InputRange>(fn, rng);
|
return transform_range<UnaryFunction, InputRange>(fn, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class UnaryFunction, class InputRange>
|
template<class UnaryFunction, class InputRange>
|
||||||
inline transform_range<UnaryFunction, const InputRange>
|
inline transform_range<UnaryFunction, const InputRange>
|
||||||
transform(const InputRange& rng, UnaryFunction fn)
|
transform(const InputRange& rng, UnaryFunction fn)
|
||||||
@ -97,7 +98,7 @@ namespace boost
|
|||||||
return transform_range<UnaryFunction, const InputRange>(fn, rng);
|
return transform_range<UnaryFunction, const InputRange>(fn, rng);
|
||||||
}
|
}
|
||||||
} // 'adaptors'
|
} // 'adaptors'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
90
include/boost/range/adaptor/type_erased.hpp
Normal file
90
include/boost/range/adaptor/type_erased.hpp
Normal 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
|
@ -15,6 +15,7 @@
|
|||||||
#include <boost/range/concepts.hpp>
|
#include <boost/range/concepts.hpp>
|
||||||
#include <boost/range/detail/range_return.hpp>
|
#include <boost/range/detail/range_return.hpp>
|
||||||
#include <boost/range/value_type.hpp>
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
@ -22,6 +23,218 @@ namespace boost
|
|||||||
namespace range
|
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_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_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_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<BinaryPredicate>::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_impl(first, last, count,
|
||||||
|
value, pred, cat_t());
|
||||||
|
}
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
/// \brief template function search
|
/// \brief template function search
|
||||||
///
|
///
|
||||||
/// range-based version of the search std algorithm
|
/// 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)
|
search_n(ForwardRange& rng, Integer count, const Value& value)
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
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
|
/// \overload
|
||||||
@ -45,7 +258,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
|||||||
search_n(const ForwardRange& rng, Integer count, const Value& value)
|
search_n(const ForwardRange& rng, Integer count, const Value& value)
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
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
|
/// \overload
|
||||||
@ -58,7 +271,7 @@ search_n(ForwardRange& rng, Integer count, const Value& value,
|
|||||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
|
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
|
||||||
return std::search_n(boost::begin(rng), boost::end(rng),
|
return range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
|
||||||
count, value, binary_pred);
|
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((ForwardRangeConcept<const ForwardRange>));
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
|
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_impl(boost::begin(rng), boost::end(rng),
|
||||||
count, value, binary_pred);
|
count, value, binary_pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +299,7 @@ search_n(ForwardRange& rng, Integer count, const Value& value)
|
|||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
return range_return<ForwardRange,re>::
|
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),
|
count, value),
|
||||||
rng);
|
rng);
|
||||||
}
|
}
|
||||||
@ -99,7 +312,7 @@ search_n(const ForwardRange& rng, Integer count, const Value& value)
|
|||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||||
return range_return<const ForwardRange,re>::
|
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),
|
count, value),
|
||||||
rng);
|
rng);
|
||||||
}
|
}
|
||||||
@ -116,7 +329,7 @@ search_n(ForwardRange& rng, Integer count, const Value& value,
|
|||||||
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
|
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
|
||||||
const Value&>));
|
const Value&>));
|
||||||
return range_return<ForwardRange,re>::
|
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, pred),
|
count, value, pred),
|
||||||
rng);
|
rng);
|
||||||
}
|
}
|
||||||
@ -133,7 +346,7 @@ search_n(const ForwardRange& rng, Integer count, const Value& value,
|
|||||||
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
|
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
|
||||||
const Value&>));
|
const Value&>));
|
||||||
return range_return<const ForwardRange,re>::
|
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, pred),
|
count, value, pred),
|
||||||
rng);
|
rng);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace boost
|
|||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
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(rng1), boost::end(rng1),
|
||||||
boost::begin(rng2), boost::end(rng2),
|
boost::begin(rng2), boost::end(rng2),
|
||||||
out, fun);
|
out, fun);
|
||||||
|
@ -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
|
#ifndef BOOST_RANGE_COMBINE_HPP
|
||||||
#define BOOST_RANGE_COMBINE_HPP
|
#define BOOST_RANGE_COMBINE_HPP
|
||||||
|
|
||||||
|
@ -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
|
#ifndef BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
|
||||||
#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
|
#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -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
|
#ifndef BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
|
||||||
#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
|
#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -290,6 +290,20 @@ namespace boost
|
|||||||
return *--last;
|
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
|
reference operator[]( difference_type at ) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( at >= 0 && at < size() );
|
BOOST_ASSERT( at >= 0 && at < size() );
|
||||||
|
49
include/boost/range/size.hpp
Executable file → Normal file
49
include/boost/range/size.hpp
Executable file → Normal file
@ -15,20 +15,55 @@
|
|||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/range/begin.hpp>
|
#include <boost/range/begin.hpp>
|
||||||
#include <boost/range/end.hpp>
|
#include <boost/range/end.hpp>
|
||||||
#include <boost/range/difference_type.hpp>
|
#include <boost/range/difference_type.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace range_detail
|
||||||
template< class T >
|
|
||||||
inline BOOST_DEDUCED_TYPENAME range_difference<T>::type size( const T& r )
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( (boost::end( r ) - boost::begin( r )) >= 0 &&
|
template< class SinglePassRange >
|
||||||
"reachability invariant broken!" );
|
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
|
||||||
return boost::end( r ) - boost::begin( r );
|
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'
|
} // namespace 'boost'
|
||||||
|
Reference in New Issue
Block a user