mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2024-12-22 23:15:39 +00:00
Bundle Boost.Range (from 1.57.0).
This commit is contained in:
parent
24eb93900c
commit
2d497719ff
23
boost/range.hpp
Normal file
23
boost/range.hpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2003-2004. 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_HPP_27_07_04
|
||||||
|
#define BOOST_RANGE_HPP_27_07_04
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/functions.hpp>
|
||||||
|
#include <boost/range/metafunctions.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/sub_range.hpp>
|
||||||
|
|
||||||
|
#endif
|
237
boost/range/adaptor/adjacent_filtered.hpp
Normal file
237
boost/range/adaptor/adjacent_filtered.hpp
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
// 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_ADJACENT_FILTER_IMPL_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning( push )
|
||||||
|
#pragma warning( disable : 4355 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/next_prior.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class Iter, class Pred, bool default_pass >
|
||||||
|
class skip_iterator
|
||||||
|
: public boost::iterator_adaptor<
|
||||||
|
skip_iterator<Iter,Pred,default_pass>,
|
||||||
|
Iter,
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
|
||||||
|
boost::forward_traversal_tag,
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
|
||||||
|
>
|
||||||
|
, private Pred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_adaptor<
|
||||||
|
skip_iterator<Iter,Pred,default_pass>,
|
||||||
|
Iter,
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
|
||||||
|
boost::forward_traversal_tag,
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
|
||||||
|
> base_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Pred pred_t;
|
||||||
|
typedef Iter iter_t;
|
||||||
|
|
||||||
|
skip_iterator() : m_last() {}
|
||||||
|
|
||||||
|
skip_iterator(iter_t it, iter_t last, const Pred& pred)
|
||||||
|
: base_t(it)
|
||||||
|
, pred_t(pred)
|
||||||
|
, m_last(last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIter>
|
||||||
|
skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
|
||||||
|
: base_t(other.base())
|
||||||
|
, pred_t(other)
|
||||||
|
, m_last(other.m_last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
iter_t& it = this->base_reference();
|
||||||
|
BOOST_ASSERT( it != m_last );
|
||||||
|
pred_t& bi_pred = *this;
|
||||||
|
iter_t prev = it;
|
||||||
|
++it;
|
||||||
|
if (it != m_last)
|
||||||
|
{
|
||||||
|
if (default_pass)
|
||||||
|
{
|
||||||
|
while (it != m_last && !bi_pred(*prev, *it))
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
++prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; it != m_last; ++it, ++prev)
|
||||||
|
{
|
||||||
|
if (bi_pred(*prev, *it))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter_t m_last;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class P, class R, bool default_pass >
|
||||||
|
struct adjacent_filtered_range
|
||||||
|
: iterator_range< skip_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
|
||||||
|
P,
|
||||||
|
default_pass
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef skip_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
|
||||||
|
P,
|
||||||
|
default_pass
|
||||||
|
>
|
||||||
|
skip_iter;
|
||||||
|
|
||||||
|
typedef iterator_range<skip_iter>
|
||||||
|
base_range;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct adjacent_holder : holder<T>
|
||||||
|
{
|
||||||
|
adjacent_holder( T r ) : holder<T>(r)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct adjacent_excl_holder : holder<T>
|
||||||
|
{
|
||||||
|
adjacent_excl_holder( T r ) : holder<T>(r)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class ForwardRng, class BinPredicate >
|
||||||
|
inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
|
||||||
|
operator|( ForwardRng& r,
|
||||||
|
const adjacent_holder<BinPredicate>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
|
||||||
|
|
||||||
|
return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class ForwardRng, class BinPredicate >
|
||||||
|
inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
|
||||||
|
operator|( const ForwardRng& r,
|
||||||
|
const adjacent_holder<BinPredicate>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
|
||||||
|
|
||||||
|
return adjacent_filtered_range<BinPredicate,
|
||||||
|
const ForwardRng, true>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class ForwardRng, class BinPredicate >
|
||||||
|
inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
|
||||||
|
operator|( ForwardRng& r,
|
||||||
|
const adjacent_excl_holder<BinPredicate>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
|
||||||
|
return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class ForwardRng, class BinPredicate >
|
||||||
|
inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
|
||||||
|
operator|( const ForwardRng& r,
|
||||||
|
const adjacent_excl_holder<BinPredicate>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
|
||||||
|
return adjacent_filtered_range<BinPredicate,
|
||||||
|
const ForwardRng, false>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
// 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_filtered_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::forwarder<range_detail::adjacent_holder>
|
||||||
|
adjacent_filtered =
|
||||||
|
range_detail::forwarder<range_detail::adjacent_holder>();
|
||||||
|
|
||||||
|
const range_detail::forwarder<range_detail::adjacent_excl_holder>
|
||||||
|
adjacent_filtered_excl =
|
||||||
|
range_detail::forwarder<range_detail::adjacent_excl_holder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardRng, class BinPredicate>
|
||||||
|
inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
|
||||||
|
adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
|
||||||
|
return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardRng, class BinPredicate>
|
||||||
|
inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
|
||||||
|
adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
|
||||||
|
return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning( pop )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
80
boost/range/adaptor/argument_fwd.hpp
Normal file
80
boost/range/adaptor/argument_fwd.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// 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_ARGUMENT_FWD_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4512) // assignment operator could not be generated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class T >
|
||||||
|
struct holder
|
||||||
|
{
|
||||||
|
T val;
|
||||||
|
holder( T t ) : val(t)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct holder2
|
||||||
|
{
|
||||||
|
T val1, val2;
|
||||||
|
holder2( T t, T u ) : val1(t), val2(u)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< template<class> class Holder >
|
||||||
|
struct forwarder
|
||||||
|
{
|
||||||
|
template< class T >
|
||||||
|
Holder<T> operator()( T t ) const
|
||||||
|
{
|
||||||
|
return Holder<T>(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< template<class> class Holder >
|
||||||
|
struct forwarder2
|
||||||
|
{
|
||||||
|
template< class T >
|
||||||
|
Holder<T> operator()( T t, T u ) const
|
||||||
|
{
|
||||||
|
return Holder<T>(t,u);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< template<class,class> class Holder >
|
||||||
|
struct forwarder2TU
|
||||||
|
{
|
||||||
|
template< class T, class U >
|
||||||
|
Holder<T, U> operator()( T t, U u ) const
|
||||||
|
{
|
||||||
|
return Holder<T, U>(t, u);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
68
boost/range/adaptor/copied.hpp
Normal file
68
boost/range/adaptor/copied.hpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen, Neil Groves 2006. 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_COPIED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_COPIED_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/adaptor/sliced.hpp>
|
||||||
|
#include <boost/range/size_type.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
struct copied
|
||||||
|
{
|
||||||
|
copied(std::size_t t_, std::size_t u_)
|
||||||
|
: t(t_), u(u_) {}
|
||||||
|
|
||||||
|
std::size_t t;
|
||||||
|
std::size_t u;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class CopyableRandomAccessRange>
|
||||||
|
inline CopyableRandomAccessRange
|
||||||
|
operator|(const CopyableRandomAccessRange& r, const copied& f)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
RandomAccessRangeConcept<const CopyableRandomAccessRange>));
|
||||||
|
|
||||||
|
iterator_range<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<
|
||||||
|
const CopyableRandomAccessRange
|
||||||
|
>::type
|
||||||
|
> temp(adaptors::slice(r, f.t, f.u));
|
||||||
|
|
||||||
|
return CopyableRandomAccessRange(temp.begin(), temp.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class CopyableRandomAccessRange>
|
||||||
|
inline CopyableRandomAccessRange
|
||||||
|
copy(const CopyableRandomAccessRange& rng, std::size_t t, std::size_t u)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
RandomAccessRangeConcept<const CopyableRandomAccessRange>));
|
||||||
|
|
||||||
|
iterator_range<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<
|
||||||
|
const CopyableRandomAccessRange
|
||||||
|
>::type
|
||||||
|
> temp(adaptors::slice(rng, t, u));
|
||||||
|
|
||||||
|
return CopyableRandomAccessRange( temp.begin(), temp.end() );
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // include guard
|
109
boost/range/adaptor/define_adaptor.hpp
Normal file
109
boost/range/adaptor/define_adaptor.hpp
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
||||||
|
#define BOOST_DEFINE_RANGE_ADAPTOR( adaptor_name, range_adaptor ) \
|
||||||
|
struct adaptor_name##_forwarder {}; \
|
||||||
|
\
|
||||||
|
template<typename Range> range_adaptor <Range> \
|
||||||
|
operator|(Range& rng, adaptor_name##_forwarder) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <Range>( rng ); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<typename Range> range_adaptor <const Range> \
|
||||||
|
operator|(const Range& rng, adaptor_name##_forwarder) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <const Range>( rng ); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static adaptor_name##_forwarder adaptor_name = adaptor_name##_forwarder(); \
|
||||||
|
\
|
||||||
|
template<typename Range> \
|
||||||
|
range_adaptor <Range> \
|
||||||
|
make_##adaptor_name(Range& rng) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <Range>(rng); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<typename Range> \
|
||||||
|
range_adaptor <const Range> \
|
||||||
|
make_##adaptor_name(const Range& rng) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <const Range>(rng); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \
|
||||||
|
struct adaptor_name \
|
||||||
|
{ \
|
||||||
|
explicit adaptor_name (arg1_type arg1_) \
|
||||||
|
: arg1(arg1_) {} \
|
||||||
|
arg1_type arg1; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template<typename Range> range_adaptor <Range> \
|
||||||
|
operator|(Range& rng, adaptor_name args) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <Range>(rng, args.arg1); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<typename Range> range_adaptor <const Range> \
|
||||||
|
operator|(const Range& rng, adaptor_name args) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <const Range>(rng, args.arg1); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<typename Range> \
|
||||||
|
range_adaptor <Range> \
|
||||||
|
make_##adaptor_name(Range& rng, arg1_type arg1) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <Range>(rng, arg1); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<typename Range> \
|
||||||
|
range_adaptor <const Range> \
|
||||||
|
make_##adaptor_name(const Range& rng, arg1_type arg1) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <const Range>(rng, arg1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_RANGE_ADAPTOR_2( adaptor_name, range_adaptor, arg1_type, arg2_type ) \
|
||||||
|
struct adaptor_name \
|
||||||
|
{ \
|
||||||
|
explicit adaptor_name (arg1_type arg1_, arg2_type arg2_) \
|
||||||
|
: arg1(arg1_), arg2(arg2_) {} \
|
||||||
|
arg1_type arg1; \
|
||||||
|
arg2_type arg2; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template<typename Range> range_adaptor <Range> \
|
||||||
|
operator|(Range& rng, adaptor_name args) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <Range>(rng, args.arg1, args.arg2); \
|
||||||
|
} \
|
||||||
|
template<typename Range> \
|
||||||
|
range_adaptor <Range> \
|
||||||
|
make_##adaptor_name(Range& rng, arg1_type arg1, arg2_type arg2) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <Range>(rng, arg1, arg2); \
|
||||||
|
} \
|
||||||
|
template<typename Range> \
|
||||||
|
range_adaptor <const Range> \
|
||||||
|
make_##adaptor_name(const Range& rng, arg1_type arg1, arg2_type arg2) \
|
||||||
|
{ \
|
||||||
|
return range_adaptor <const Range>(rng, arg1, arg2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // include guard
|
118
boost/range/adaptor/filtered.hpp
Normal file
118
boost/range/adaptor/filtered.hpp
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// 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_FILTERED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_FILTERED_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/detail/default_constructible_unary_fn.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class P, class R >
|
||||||
|
struct filtered_range :
|
||||||
|
boost::iterator_range<
|
||||||
|
boost::filter_iterator<
|
||||||
|
typename default_constructible_unary_fn_gen<P, bool>::type,
|
||||||
|
typename range_iterator<R>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_range<
|
||||||
|
boost::filter_iterator<
|
||||||
|
typename default_constructible_unary_fn_gen<P, bool>::type,
|
||||||
|
typename range_iterator<R>::type
|
||||||
|
>
|
||||||
|
> base;
|
||||||
|
public:
|
||||||
|
typedef typename default_constructible_unary_fn_gen<P, bool>::type
|
||||||
|
pred_t;
|
||||||
|
|
||||||
|
filtered_range(P p, R& r)
|
||||||
|
: base(make_filter_iterator(pred_t(p),
|
||||||
|
boost::begin(r), boost::end(r)),
|
||||||
|
make_filter_iterator(pred_t(p),
|
||||||
|
boost::end(r), boost::end(r)))
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct filter_holder : holder<T>
|
||||||
|
{
|
||||||
|
filter_holder( T r ) : holder<T>(r)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class ForwardRange, class Predicate >
|
||||||
|
inline filtered_range<Predicate, ForwardRange>
|
||||||
|
operator|(ForwardRange& r,
|
||||||
|
const filter_holder<Predicate>& f)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return filtered_range<Predicate, ForwardRange>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class ForwardRange, class Predicate >
|
||||||
|
inline filtered_range<Predicate, const ForwardRange>
|
||||||
|
operator|(const ForwardRange& r,
|
||||||
|
const filter_holder<Predicate>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
ForwardRangeConcept<const ForwardRange>));
|
||||||
|
return filtered_range<Predicate, const ForwardRange>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
// Unusual use of 'using' is intended to bring filter_range into the boost namespace
|
||||||
|
// while leaving the mechanics of the '|' operator in range_detail and maintain
|
||||||
|
// 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::filtered_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::forwarder<range_detail::filter_holder>
|
||||||
|
filtered =
|
||||||
|
range_detail::forwarder<range_detail::filter_holder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardRange, class Predicate>
|
||||||
|
inline filtered_range<Predicate, ForwardRange>
|
||||||
|
filter(ForwardRange& rng, Predicate filter_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
|
||||||
|
return range_detail::filtered_range<Predicate, ForwardRange>( filter_pred, rng );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardRange, class Predicate>
|
||||||
|
inline filtered_range<Predicate, const ForwardRange>
|
||||||
|
filter(const ForwardRange& rng, Predicate filter_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
ForwardRangeConcept<const ForwardRange>));
|
||||||
|
|
||||||
|
return range_detail::filtered_range<Predicate, const ForwardRange>( filter_pred, rng );
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
229
boost/range/adaptor/formatted.hpp
Normal file
229
boost/range/adaptor/formatted.hpp
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2014.
|
||||||
|
// Use, modification and distribution is subject to the Boost Software
|
||||||
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// For more information, see http://www.boost.org/libs/range/
|
||||||
|
//
|
||||||
|
#ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/type_traits/is_array.hpp>
|
||||||
|
#include <boost/type_traits/remove_extent.hpp>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Sep, typename Prefix, typename Postfix>
|
||||||
|
struct formatted_holder
|
||||||
|
{
|
||||||
|
typedef typename boost::mpl::if_<
|
||||||
|
boost::is_array<Sep>,
|
||||||
|
const typename boost::remove_extent<Sep>::type*,
|
||||||
|
Sep
|
||||||
|
>::type separator_t;
|
||||||
|
|
||||||
|
typedef typename boost::mpl::if_<
|
||||||
|
boost::is_array<Prefix>,
|
||||||
|
const typename boost::remove_extent<Prefix>::type*,
|
||||||
|
Prefix
|
||||||
|
>::type prefix_t;
|
||||||
|
|
||||||
|
typedef typename boost::mpl::if_<
|
||||||
|
boost::is_array<Postfix>,
|
||||||
|
const typename boost::remove_extent<Postfix>::type*,
|
||||||
|
Postfix
|
||||||
|
>::type postfix_t;
|
||||||
|
|
||||||
|
formatted_holder(
|
||||||
|
const separator_t& sep,
|
||||||
|
const prefix_t& prefix,
|
||||||
|
const postfix_t& postfix)
|
||||||
|
: m_sep(sep)
|
||||||
|
, m_prefix(prefix)
|
||||||
|
, m_postfix(postfix)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
separator_t m_sep;
|
||||||
|
prefix_t m_prefix;
|
||||||
|
postfix_t m_postfix;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter, typename Sep, typename Prefix, typename Postfix>
|
||||||
|
class formatted_range
|
||||||
|
: public boost::iterator_range<Iter>
|
||||||
|
{
|
||||||
|
typedef formatted_holder<Sep,Prefix,Postfix> holder_t;
|
||||||
|
public:
|
||||||
|
formatted_range(Iter first, Iter last, const holder_t& holder)
|
||||||
|
: boost::iterator_range<Iter>(first, last)
|
||||||
|
, m_holder(holder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OStream>
|
||||||
|
void write(OStream& out) const
|
||||||
|
{
|
||||||
|
Iter it(this->begin());
|
||||||
|
out << m_holder.m_prefix;
|
||||||
|
if (it != this->end())
|
||||||
|
{
|
||||||
|
out << *it;
|
||||||
|
for (++it; it != this->end(); ++it)
|
||||||
|
{
|
||||||
|
out << m_holder.m_sep << *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << m_holder.m_postfix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
holder_t m_holder;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename SinglePassRange,
|
||||||
|
typename Sep,
|
||||||
|
typename Prefix,
|
||||||
|
typename Postfix
|
||||||
|
>
|
||||||
|
inline range_detail::formatted_range<
|
||||||
|
typename range_iterator<const SinglePassRange>::type, Sep, Prefix, Postfix
|
||||||
|
>
|
||||||
|
operator|(
|
||||||
|
const SinglePassRange& rng,
|
||||||
|
const range_detail::formatted_holder<Sep,Prefix,Postfix>& holder
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef typename range_iterator<const SinglePassRange>::type iterator;
|
||||||
|
return range_detail::formatted_range<iterator, Sep, Prefix, Postfix>(
|
||||||
|
boost::begin(rng), boost::end(rng), holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Char, typename Traits, typename Iter, typename Sep,
|
||||||
|
typename Prefix, typename Postfix>
|
||||||
|
std::basic_ostream<Char, Traits>&
|
||||||
|
operator<<(
|
||||||
|
std::basic_ostream<Char, Traits>& out,
|
||||||
|
const formatted_range<Iter, Sep, Prefix, Postfix>& writer)
|
||||||
|
{
|
||||||
|
writer.write(out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Sep, typename Prefix, typename Postfix>
|
||||||
|
range_detail::formatted_holder<Sep, Prefix, Postfix>
|
||||||
|
formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix)
|
||||||
|
{
|
||||||
|
return range_detail::formatted_holder<Sep,Prefix,Postfix>(
|
||||||
|
sep, prefix, postfix);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Sep, typename Prefix>
|
||||||
|
range_detail::formatted_holder<Sep, Prefix, char>
|
||||||
|
formatted(const Sep& sep, const Prefix& prefix)
|
||||||
|
{
|
||||||
|
return range_detail::formatted_holder<Sep, Prefix, char>(sep, prefix, '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Sep>
|
||||||
|
range_detail::formatted_holder<Sep, char, char>
|
||||||
|
formatted(const Sep& sep)
|
||||||
|
{
|
||||||
|
return range_detail::formatted_holder<Sep, char, char>(sep, '{', '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline range_detail::formatted_holder<char, char, char>
|
||||||
|
formatted()
|
||||||
|
{
|
||||||
|
return range_detail::formatted_holder<char, char, char>(',', '{', '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
using range_detail::formatted_range;
|
||||||
|
|
||||||
|
template<typename SinglePassRange, typename Sep, typename Prefix,
|
||||||
|
typename Postfix>
|
||||||
|
inline boost::range_detail::formatted_range<
|
||||||
|
typename boost::range_iterator<const SinglePassRange>::type,
|
||||||
|
Sep, Prefix, Postfix
|
||||||
|
>
|
||||||
|
format(
|
||||||
|
const SinglePassRange& rng,
|
||||||
|
const Sep& sep,
|
||||||
|
const Prefix& prefix,
|
||||||
|
const Postfix& postfix
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef typename boost::range_iterator<const SinglePassRange>::type
|
||||||
|
iterator_t;
|
||||||
|
|
||||||
|
typedef boost::range_detail::formatted_range<
|
||||||
|
iterator_t, Sep, Prefix, Postfix> result_t;
|
||||||
|
|
||||||
|
typedef boost::range_detail::formatted_holder<Sep, Prefix, Postfix>
|
||||||
|
holder_t;
|
||||||
|
|
||||||
|
return result_t(boost::begin(rng), boost::end(rng),
|
||||||
|
holder_t(sep, prefix, postfix));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename SinglePassRange, typename Sep, typename Prefix>
|
||||||
|
inline boost::range_detail::formatted_range<
|
||||||
|
typename boost::range_iterator<const SinglePassRange>::type,
|
||||||
|
Sep, Prefix, char
|
||||||
|
>
|
||||||
|
format(
|
||||||
|
const SinglePassRange& rng,
|
||||||
|
const Sep& sep,
|
||||||
|
const Prefix& prefix)
|
||||||
|
{
|
||||||
|
return adaptors::format<SinglePassRange, Sep, Prefix, char>(rng, sep, prefix, '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename SinglePassRange, typename Sep>
|
||||||
|
inline boost::range_detail::formatted_range<
|
||||||
|
typename boost::range_iterator<const SinglePassRange>::type,
|
||||||
|
Sep, char, char
|
||||||
|
>
|
||||||
|
format(const SinglePassRange& rng, const Sep& sep)
|
||||||
|
{
|
||||||
|
return adaptors::format<SinglePassRange, Sep, char, char>(rng, sep, '{', '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename SinglePassRange>
|
||||||
|
inline boost::range_detail::formatted_range<
|
||||||
|
typename boost::range_iterator<const SinglePassRange>::type,
|
||||||
|
char, char, char
|
||||||
|
>
|
||||||
|
format(const SinglePassRange& rng)
|
||||||
|
{
|
||||||
|
return adaptors::format<SinglePassRange, char, char, char>(rng, ',', '{', '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace adaptors
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
using boost::range_detail::formatted_range;
|
||||||
|
} // namespace range
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
370
boost/range/adaptor/indexed.hpp
Normal file
370
boost/range/adaptor/indexed.hpp
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
// Copyright 2014 Neil Groves
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 Ilya Murav'jov
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// Credits:
|
||||||
|
// My (Neil's) first indexed adaptor was hindered by having the underlying
|
||||||
|
// iterator return the same reference as the wrapped iterator. This meant that
|
||||||
|
// to obtain the index one had to get to the index_iterator and call the
|
||||||
|
// index() function on it. Ilya politely pointed out that this was useless in
|
||||||
|
// a number of scenarios since one naturally hides the use of iterators in
|
||||||
|
// good range-based code. Ilya provided a new interface (which has remained)
|
||||||
|
// and a first implementation. Much of this original implementation has
|
||||||
|
// been simplified and now supports more compilers and platforms.
|
||||||
|
//
|
||||||
|
#ifndef BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/traversal.hpp>
|
||||||
|
#include <boost/range/size.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
|
||||||
|
struct indexed
|
||||||
|
{
|
||||||
|
explicit indexed(std::ptrdiff_t x = 0)
|
||||||
|
: val(x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::ptrdiff_t val;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace adaptors
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
// Why yet another "pair" class:
|
||||||
|
// - std::pair can't store references
|
||||||
|
// - no need for typing for index type (default to "std::ptrdiff_t"); this is
|
||||||
|
// useful in BOOST_FOREACH() expressions that have pitfalls with commas
|
||||||
|
// ( see http://www.boost.org/doc/libs/1_44_0/doc/html/foreach/pitfalls.html )
|
||||||
|
// - meaningful access functions index(), value()
|
||||||
|
template<class T, class Indexable = std::ptrdiff_t>
|
||||||
|
class index_value
|
||||||
|
: public tuple<Indexable, T>
|
||||||
|
{
|
||||||
|
typedef tuple<Indexable, T> base_t;
|
||||||
|
|
||||||
|
template<int N>
|
||||||
|
struct iv_types
|
||||||
|
{
|
||||||
|
typedef typename tuples::element<N, base_t>::type n_type;
|
||||||
|
|
||||||
|
typedef typename tuples::access_traits<n_type>::non_const_type non_const_type;
|
||||||
|
typedef typename tuples::access_traits<n_type>::const_type const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename iv_types<0>::non_const_type index_type;
|
||||||
|
typedef typename iv_types<0>::const_type const_index_type;
|
||||||
|
typedef typename iv_types<1>::non_const_type value_type;
|
||||||
|
typedef typename iv_types<1>::const_type const_value_type;
|
||||||
|
|
||||||
|
index_value()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
index_value(typename tuples::access_traits<Indexable>::parameter_type t0,
|
||||||
|
typename tuples::access_traits<T>::parameter_type t1)
|
||||||
|
: base_t(t0, t1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// member functions index(), value() (non-const and const)
|
||||||
|
index_type index()
|
||||||
|
{
|
||||||
|
return boost::tuples::get<0>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const_index_type index() const
|
||||||
|
{
|
||||||
|
return boost::tuples::get<0>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type value()
|
||||||
|
{
|
||||||
|
return boost::tuples::get<1>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const_value_type value() const
|
||||||
|
{
|
||||||
|
return boost::tuples::get<1>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Iter>
|
||||||
|
struct indexed_iterator_value_type
|
||||||
|
{
|
||||||
|
typedef ::boost::range::index_value<
|
||||||
|
typename iterator_reference<Iter>::type,
|
||||||
|
typename iterator_difference<Iter>::type
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Meta-function to get the traversal for the range and therefore iterator
|
||||||
|
// returned by the indexed adaptor for a specified iterator type.
|
||||||
|
//
|
||||||
|
// Random access -> Random access
|
||||||
|
// Bidirectional -> Forward
|
||||||
|
// Forward -> Forward
|
||||||
|
// SinglePass -> SinglePass
|
||||||
|
//
|
||||||
|
// The rationale for demoting a Bidirectional input to Forward is that the end
|
||||||
|
// iterator cannot cheaply have an index computed for it. Therefore I chose to
|
||||||
|
// demote to forward traversal. I can maintain the ability to traverse randomly
|
||||||
|
// when the input is Random Access since the index for the end iterator is cheap
|
||||||
|
// to compute.
|
||||||
|
template<typename Iter>
|
||||||
|
struct indexed_traversal
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef typename iterator_traversal<Iter>::type wrapped_traversal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
is_convertible<wrapped_traversal, random_access_traversal_tag>,
|
||||||
|
random_access_traversal_tag,
|
||||||
|
typename mpl::if_<
|
||||||
|
is_convertible<wrapped_traversal, bidirectional_traversal_tag>,
|
||||||
|
forward_traversal_tag,
|
||||||
|
wrapped_traversal
|
||||||
|
>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iter>
|
||||||
|
class indexed_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
indexed_iterator<Iter>,
|
||||||
|
typename indexed_iterator_value_type<Iter>::type,
|
||||||
|
typename indexed_traversal<Iter>::type,
|
||||||
|
typename indexed_iterator_value_type<Iter>::type,
|
||||||
|
typename iterator_difference<Iter>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Iter wrapped;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef iterator_facade<
|
||||||
|
indexed_iterator<wrapped>,
|
||||||
|
typename indexed_iterator_value_type<wrapped>::type,
|
||||||
|
typename indexed_traversal<wrapped>::type,
|
||||||
|
typename indexed_iterator_value_type<wrapped>::type,
|
||||||
|
typename iterator_difference<wrapped>::type
|
||||||
|
> base_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_t::difference_type difference_type;
|
||||||
|
typedef typename base_t::reference reference;
|
||||||
|
typedef typename base_t::difference_type index_type;
|
||||||
|
|
||||||
|
indexed_iterator()
|
||||||
|
: m_it()
|
||||||
|
, m_index()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OtherWrapped>
|
||||||
|
indexed_iterator(
|
||||||
|
const indexed_iterator<OtherWrapped>& other,
|
||||||
|
typename enable_if<is_convertible<OtherWrapped, wrapped> >::type* = 0
|
||||||
|
)
|
||||||
|
: m_it(other.get())
|
||||||
|
, m_index(other.get_index())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit indexed_iterator(wrapped it, index_type index)
|
||||||
|
: m_it(it)
|
||||||
|
, m_index(index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapped get() const
|
||||||
|
{
|
||||||
|
return m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
index_type get_index() const
|
||||||
|
{
|
||||||
|
return m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class boost::iterator_core_access;
|
||||||
|
|
||||||
|
reference dereference() const
|
||||||
|
{
|
||||||
|
return reference(m_index, *m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(const indexed_iterator& other) const
|
||||||
|
{
|
||||||
|
return m_it == other.m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
++m_index;
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT_MSG(m_index > 0, "indexed Iterator out of bounds");
|
||||||
|
--m_index;
|
||||||
|
--m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance(index_type n)
|
||||||
|
{
|
||||||
|
m_index += n;
|
||||||
|
BOOST_ASSERT_MSG(m_index >= 0, "indexed Iterator out of bounds");
|
||||||
|
m_it += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type distance_to(const indexed_iterator& other) const
|
||||||
|
{
|
||||||
|
return other.m_it - m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapped m_it;
|
||||||
|
index_type m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename SinglePassRange>
|
||||||
|
struct indexed_range
|
||||||
|
: iterator_range<
|
||||||
|
indexed_iterator<
|
||||||
|
typename range_iterator<SinglePassRange>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef iterator_range<
|
||||||
|
indexed_iterator<
|
||||||
|
typename range_iterator<SinglePassRange>::type
|
||||||
|
>
|
||||||
|
> base_t;
|
||||||
|
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
boost::SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
public:
|
||||||
|
typedef indexed_iterator<
|
||||||
|
typename range_iterator<SinglePassRange>::type
|
||||||
|
> iterator;
|
||||||
|
|
||||||
|
// Constructor for non-random access iterators.
|
||||||
|
// This sets the end iterator index to i despite this being incorrect it
|
||||||
|
// is never observable since bidirectional iterators are demoted to
|
||||||
|
// forward iterators.
|
||||||
|
indexed_range(
|
||||||
|
typename base_t::difference_type i,
|
||||||
|
SinglePassRange& r,
|
||||||
|
single_pass_traversal_tag
|
||||||
|
)
|
||||||
|
: base_t(iterator(boost::begin(r), i),
|
||||||
|
iterator(boost::end(r), i))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
indexed_range(
|
||||||
|
typename base_t::difference_type i,
|
||||||
|
SinglePassRange& r,
|
||||||
|
random_access_traversal_tag
|
||||||
|
)
|
||||||
|
: base_t(iterator(boost::begin(r), i),
|
||||||
|
iterator(boost::end(r), i + boost::size(r)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
using range_detail::indexed_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline indexed_range<SinglePassRange>
|
||||||
|
operator|(SinglePassRange& r, indexed e)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
boost::SinglePassRangeConcept<SinglePassRange>
|
||||||
|
));
|
||||||
|
return indexed_range<SinglePassRange>(
|
||||||
|
e.val, r,
|
||||||
|
typename range_traversal<SinglePassRange>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline indexed_range<const SinglePassRange>
|
||||||
|
operator|(const SinglePassRange& r, indexed e)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
boost::SinglePassRangeConcept<const SinglePassRange>
|
||||||
|
));
|
||||||
|
return indexed_range<const SinglePassRange>(
|
||||||
|
e.val, r,
|
||||||
|
typename range_traversal<const SinglePassRange>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline indexed_range<SinglePassRange>
|
||||||
|
index(
|
||||||
|
SinglePassRange& rng,
|
||||||
|
typename range_difference<SinglePassRange>::type index_value = 0)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
boost::SinglePassRangeConcept<SinglePassRange>
|
||||||
|
));
|
||||||
|
return indexed_range<SinglePassRange>(
|
||||||
|
index_value, rng,
|
||||||
|
typename range_traversal<SinglePassRange>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline indexed_range<const SinglePassRange>
|
||||||
|
index(
|
||||||
|
const SinglePassRange& rng,
|
||||||
|
typename range_difference<const SinglePassRange>::type index_value = 0)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
boost::SinglePassRangeConcept<SinglePassRange>
|
||||||
|
));
|
||||||
|
return indexed_range<const SinglePassRange>(
|
||||||
|
index_value, rng,
|
||||||
|
typename range_traversal<const SinglePassRange>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace adaptors
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
100
boost/range/adaptor/indirected.hpp
Normal file
100
boost/range/adaptor/indirected.hpp
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// 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_INDIRECTED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/indirect_iterator.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class R >
|
||||||
|
struct indirected_range :
|
||||||
|
public boost::iterator_range<
|
||||||
|
boost::indirect_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_range<
|
||||||
|
boost::indirect_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit indirected_range( R& r )
|
||||||
|
: base( r )
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct indirect_forwarder {};
|
||||||
|
|
||||||
|
template< class SinglePassRange >
|
||||||
|
inline indirected_range<SinglePassRange>
|
||||||
|
operator|( SinglePassRange& r, indirect_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return indirected_range<SinglePassRange>( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassRange >
|
||||||
|
inline indirected_range<const SinglePassRange>
|
||||||
|
operator|( const SinglePassRange& r, indirect_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return indirected_range<const SinglePassRange>( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::indirected_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::indirect_forwarder indirected =
|
||||||
|
range_detail::indirect_forwarder();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline indirected_range<SinglePassRange>
|
||||||
|
indirect(SinglePassRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
return indirected_range<SinglePassRange>(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline indirected_range<const SinglePassRange>
|
||||||
|
indirect(const SinglePassRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return indirected_range<const SinglePassRange>(rng);
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
204
boost/range/adaptor/map.hpp
Normal file
204
boost/range/adaptor/map.hpp
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
// 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_MAP_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_MAP_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/reference.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
struct map_keys_forwarder {};
|
||||||
|
struct map_values_forwarder {};
|
||||||
|
|
||||||
|
template< class Map >
|
||||||
|
struct select_first
|
||||||
|
{
|
||||||
|
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()( argument_type r ) const
|
||||||
|
{
|
||||||
|
return r.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Map >
|
||||||
|
struct select_second_mutable
|
||||||
|
{
|
||||||
|
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()( argument_type r ) const
|
||||||
|
{
|
||||||
|
return r.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Map >
|
||||||
|
struct select_second_const
|
||||||
|
{
|
||||||
|
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()( argument_type r ) const
|
||||||
|
{
|
||||||
|
return r.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class StdPairRng>
|
||||||
|
class select_first_range
|
||||||
|
: public transformed_range<
|
||||||
|
select_first<StdPairRng>,
|
||||||
|
const StdPairRng>
|
||||||
|
{
|
||||||
|
typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base;
|
||||||
|
public:
|
||||||
|
typedef select_first<StdPairRng> transform_fn_type;
|
||||||
|
typedef const StdPairRng source_range_type;
|
||||||
|
|
||||||
|
select_first_range(transform_fn_type fn, source_range_type& rng)
|
||||||
|
: base(fn, rng)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
select_first_range(const base& other) : base(other) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class StdPairRng>
|
||||||
|
class select_second_mutable_range
|
||||||
|
: public transformed_range<
|
||||||
|
select_second_mutable<StdPairRng>,
|
||||||
|
StdPairRng>
|
||||||
|
{
|
||||||
|
typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base;
|
||||||
|
public:
|
||||||
|
typedef select_second_mutable<StdPairRng> transform_fn_type;
|
||||||
|
typedef StdPairRng source_range_type;
|
||||||
|
|
||||||
|
select_second_mutable_range(transform_fn_type fn, source_range_type& rng)
|
||||||
|
: base(fn, rng)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
select_second_mutable_range(const base& other) : base(other) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class StdPairRng>
|
||||||
|
class select_second_const_range
|
||||||
|
: public transformed_range<
|
||||||
|
select_second_const<StdPairRng>,
|
||||||
|
const StdPairRng>
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
select_second_const_range(transform_fn_type fn, source_range_type& rng)
|
||||||
|
: base(fn, rng)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
select_second_const_range(const base& other) : base(other) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class StdPairRng >
|
||||||
|
inline select_first_range<StdPairRng>
|
||||||
|
operator|( const StdPairRng& r, map_keys_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const StdPairRng>));
|
||||||
|
|
||||||
|
return operator|( r,
|
||||||
|
boost::adaptors::transformed( select_first<StdPairRng>() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class StdPairRng >
|
||||||
|
inline select_second_mutable_range<StdPairRng>
|
||||||
|
operator|( StdPairRng& r, map_values_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRng>));
|
||||||
|
|
||||||
|
return operator|( r,
|
||||||
|
boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class StdPairRng >
|
||||||
|
inline select_second_const_range<StdPairRng>
|
||||||
|
operator|( const StdPairRng& r, map_values_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const StdPairRng>));
|
||||||
|
|
||||||
|
return operator|( r,
|
||||||
|
boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::select_first_range;
|
||||||
|
using range_detail::select_second_mutable_range;
|
||||||
|
using range_detail::select_second_const_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::map_keys_forwarder map_keys =
|
||||||
|
range_detail::map_keys_forwarder();
|
||||||
|
|
||||||
|
const range_detail::map_values_forwarder map_values =
|
||||||
|
range_detail::map_values_forwarder();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class StdPairRange>
|
||||||
|
inline select_first_range<StdPairRange>
|
||||||
|
keys(const StdPairRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const StdPairRange>));
|
||||||
|
|
||||||
|
return select_first_range<StdPairRange>(
|
||||||
|
range_detail::select_first<StdPairRange>(), rng );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class StdPairRange>
|
||||||
|
inline select_second_const_range<StdPairRange>
|
||||||
|
values(const StdPairRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const StdPairRange>));
|
||||||
|
|
||||||
|
return select_second_const_range<StdPairRange>(
|
||||||
|
range_detail::select_second_const<StdPairRange>(), rng );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class StdPairRange>
|
||||||
|
inline select_second_mutable_range<StdPairRange>
|
||||||
|
values(StdPairRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRange>));
|
||||||
|
|
||||||
|
return select_second_mutable_range<StdPairRange>(
|
||||||
|
range_detail::select_second_mutable<StdPairRange>(), rng );
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
169
boost/range/adaptor/replaced.hpp
Normal file
169
boost/range/adaptor/replaced.hpp
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2007. 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_REPLACED_IMPL_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/optional/optional.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class Value >
|
||||||
|
class replace_value
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef const Value& result_type;
|
||||||
|
typedef const Value& first_argument_type;
|
||||||
|
|
||||||
|
// Rationale:
|
||||||
|
// The default constructor is required to allow the transform
|
||||||
|
// iterator to properly model the iterator concept.
|
||||||
|
replace_value()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_value(const Value& from, const Value& to)
|
||||||
|
: m_impl(data(from, to))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value& operator()(const Value& x) const
|
||||||
|
{
|
||||||
|
return (x == m_impl->m_from) ? m_impl->m_to : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct data
|
||||||
|
{
|
||||||
|
data(const Value& from, const Value& to)
|
||||||
|
: m_from(from)
|
||||||
|
, m_to(to)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Value m_from;
|
||||||
|
Value m_to;
|
||||||
|
};
|
||||||
|
boost::optional<data> m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class R >
|
||||||
|
class replaced_range :
|
||||||
|
public boost::iterator_range<
|
||||||
|
boost::transform_iterator<
|
||||||
|
replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
|
||||||
|
|
||||||
|
typedef boost::iterator_range<
|
||||||
|
boost::transform_iterator<
|
||||||
|
replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
|
||||||
|
|
||||||
|
replaced_range( R& r, value_type from, value_type to )
|
||||||
|
: base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
|
||||||
|
make_transform_iterator( boost::end(r), Fn(from, to) ) )
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
class replace_holder : public holder2<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
replace_holder( const T& from, const T& to )
|
||||||
|
: holder2<T>(from, to)
|
||||||
|
{ }
|
||||||
|
private:
|
||||||
|
// not assignable
|
||||||
|
void operator=(const replace_holder&);
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class SinglePassRange >
|
||||||
|
inline replaced_range<SinglePassRange>
|
||||||
|
operator|(
|
||||||
|
SinglePassRange& r,
|
||||||
|
const replace_holder<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return replaced_range<SinglePassRange>(r, f.val1, f.val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassRange >
|
||||||
|
inline replaced_range<const SinglePassRange>
|
||||||
|
operator|(
|
||||||
|
const SinglePassRange& r,
|
||||||
|
const replace_holder<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
|
||||||
|
}
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::replaced_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::forwarder2<range_detail::replace_holder>
|
||||||
|
replaced =
|
||||||
|
range_detail::forwarder2<range_detail::replace_holder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline replaced_range<SinglePassRange>
|
||||||
|
replace(SinglePassRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return replaced_range<SinglePassRange>(rng, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline replaced_range<const SinglePassRange>
|
||||||
|
replace(const SinglePassRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return replaced_range<const SinglePassRange>(rng, from ,to);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'adaptors'
|
||||||
|
} // 'boost'
|
||||||
|
|
||||||
|
#endif // include guard
|
177
boost/range/adaptor/replaced_if.hpp
Normal file
177
boost/range/adaptor/replaced_if.hpp
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2007. 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_REPLACED_IF_IMPL_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/optional/optional.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class Pred, class Value >
|
||||||
|
class replace_value_if
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef const Value& result_type;
|
||||||
|
typedef const Value& first_argument_type;
|
||||||
|
|
||||||
|
// Rationale:
|
||||||
|
// required to allow the iterator to be default constructible.
|
||||||
|
replace_value_if()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_value_if(const Pred& pred, const Value& to)
|
||||||
|
: m_impl(data(pred, to))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value& operator()(const Value& x) const
|
||||||
|
{
|
||||||
|
return m_impl->m_pred(x) ? m_impl->m_to : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct data
|
||||||
|
{
|
||||||
|
data(const Pred& p, const Value& t)
|
||||||
|
: m_pred(p), m_to(t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Pred m_pred;
|
||||||
|
Value m_to;
|
||||||
|
};
|
||||||
|
boost::optional<data> m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Pred, class R >
|
||||||
|
class replaced_if_range :
|
||||||
|
public boost::iterator_range<
|
||||||
|
boost::transform_iterator<
|
||||||
|
replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
|
||||||
|
|
||||||
|
typedef boost::iterator_range<
|
||||||
|
boost::transform_iterator<
|
||||||
|
replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
|
||||||
|
|
||||||
|
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) ) )
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Pred, class T >
|
||||||
|
class replace_if_holder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
replace_if_holder( const Pred& pred, const T& to )
|
||||||
|
: m_pred(pred), m_to(to)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
const Pred& pred() const { return m_pred; }
|
||||||
|
const T& to() const { return m_to; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Pred m_pred;
|
||||||
|
T m_to;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Pred, class SinglePassRange >
|
||||||
|
inline replaced_if_range<Pred, SinglePassRange>
|
||||||
|
operator|(
|
||||||
|
SinglePassRange& r,
|
||||||
|
const replace_if_holder<
|
||||||
|
Pred,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return replaced_if_range<Pred, SinglePassRange>(
|
||||||
|
r, f.pred(), f.to());
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Pred, class SinglePassRange >
|
||||||
|
inline replaced_if_range<Pred, const SinglePassRange>
|
||||||
|
operator|(
|
||||||
|
const SinglePassRange& r,
|
||||||
|
const replace_if_holder<
|
||||||
|
Pred,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return replaced_if_range<Pred, const SinglePassRange>(
|
||||||
|
r, f.pred(), f.to());
|
||||||
|
}
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::replaced_if_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::forwarder2TU<range_detail::replace_if_holder>
|
||||||
|
replaced_if =
|
||||||
|
range_detail::forwarder2TU<range_detail::replace_if_holder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Pred, class SinglePassRange>
|
||||||
|
inline replaced_if_range<Pred, SinglePassRange>
|
||||||
|
replace_if(SinglePassRange& rng, Pred pred,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return range_detail::replaced_if_range<Pred, SinglePassRange>(
|
||||||
|
rng, pred, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Pred, class SinglePassRange>
|
||||||
|
inline replaced_if_range<Pred, const SinglePassRange>
|
||||||
|
replace_if(
|
||||||
|
const SinglePassRange& rng,
|
||||||
|
Pred pred,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type to)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return range_detail::replaced_if_range<Pred, const SinglePassRange>(
|
||||||
|
rng, pred, to);
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
} // 'boost'
|
||||||
|
|
||||||
|
#endif // include guard
|
103
boost/range/adaptor/reversed.hpp
Normal file
103
boost/range/adaptor/reversed.hpp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// 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_REVERSED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_REVERSED_HPP
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/reverse_iterator.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class R >
|
||||||
|
struct reversed_range :
|
||||||
|
public boost::iterator_range<
|
||||||
|
boost::reverse_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_range<
|
||||||
|
boost::reverse_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef boost::reverse_iterator<BOOST_DEDUCED_TYPENAME range_iterator<R>::type> iterator;
|
||||||
|
|
||||||
|
explicit reversed_range( R& r )
|
||||||
|
: base( iterator(boost::end(r)), iterator(boost::begin(r)) )
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reverse_forwarder {};
|
||||||
|
|
||||||
|
template< class BidirectionalRange >
|
||||||
|
inline reversed_range<BidirectionalRange>
|
||||||
|
operator|( BidirectionalRange& r, reverse_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
BidirectionalRangeConcept<BidirectionalRange>));
|
||||||
|
|
||||||
|
return reversed_range<BidirectionalRange>( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class BidirectionalRange >
|
||||||
|
inline reversed_range<const BidirectionalRange>
|
||||||
|
operator|( const BidirectionalRange& r, reverse_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
BidirectionalRangeConcept<const BidirectionalRange>));
|
||||||
|
|
||||||
|
return reversed_range<const BidirectionalRange>( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::reversed_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::reverse_forwarder reversed =
|
||||||
|
range_detail::reverse_forwarder();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline reversed_range<BidirectionalRange>
|
||||||
|
reverse(BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
BidirectionalRangeConcept<BidirectionalRange>));
|
||||||
|
|
||||||
|
return reversed_range<BidirectionalRange>(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline reversed_range<const BidirectionalRange>
|
||||||
|
reverse(const BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
BidirectionalRangeConcept<const BidirectionalRange>));
|
||||||
|
|
||||||
|
return reversed_range<const BidirectionalRange>(rng);
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
} // 'boost'
|
||||||
|
|
||||||
|
#endif
|
96
boost/range/adaptor/sliced.hpp
Normal file
96
boost/range/adaptor/sliced.hpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// 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_SLICED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_SLICED_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/size_type.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
struct sliced
|
||||||
|
{
|
||||||
|
sliced(std::size_t t_, std::size_t u_)
|
||||||
|
: t(t_), u(u_) {}
|
||||||
|
std::size_t t;
|
||||||
|
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::next(boost::begin(rng), t),
|
||||||
|
boost::next(boost::begin(rng), u))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class RandomAccessRange >
|
||||||
|
inline sliced_range<RandomAccessRange>
|
||||||
|
slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
RandomAccessRangeConcept<RandomAccessRange>));
|
||||||
|
|
||||||
|
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<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_RANGE_CONCEPT_ASSERT((
|
||||||
|
RandomAccessRangeConcept<const RandomAccessRange>));
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
RandomAccessRangeConcept<RandomAccessRange>));
|
||||||
|
|
||||||
|
return sliced_range<RandomAccessRange>( r, f.t, f.u );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class RandomAccessRange >
|
||||||
|
inline sliced_range<const RandomAccessRange>
|
||||||
|
operator|( const RandomAccessRange& r, const sliced& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
RandomAccessRangeConcept<const RandomAccessRange>));
|
||||||
|
|
||||||
|
return sliced_range<const RandomAccessRange>( r, f.t, f.u );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace adaptors
|
||||||
|
using adaptors::sliced_range;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
697
boost/range/adaptor/strided.hpp
Normal file
697
boost/range/adaptor/strided.hpp
Normal file
|
@ -0,0 +1,697 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2007. 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_STRIDED_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
// strided_iterator for wrapping a forward traversal iterator
|
||||||
|
template<class BaseIterator, class Category>
|
||||||
|
class strided_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
strided_iterator<BaseIterator, Category>
|
||||||
|
, typename iterator_value<BaseIterator>::type
|
||||||
|
, forward_traversal_tag
|
||||||
|
, typename iterator_reference<BaseIterator>::type
|
||||||
|
, typename iterator_difference<BaseIterator>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
friend class ::boost::iterator_core_access;
|
||||||
|
|
||||||
|
typedef iterator_facade<
|
||||||
|
strided_iterator<BaseIterator, Category>
|
||||||
|
, typename iterator_value<BaseIterator>::type
|
||||||
|
, forward_traversal_tag
|
||||||
|
, typename iterator_reference<BaseIterator>::type
|
||||||
|
, typename iterator_difference<BaseIterator>::type
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename super_t::difference_type difference_type;
|
||||||
|
typedef typename super_t::reference reference;
|
||||||
|
typedef BaseIterator base_iterator;
|
||||||
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
strided_iterator()
|
||||||
|
: m_it()
|
||||||
|
, m_last()
|
||||||
|
, m_stride()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
strided_iterator(base_iterator it,
|
||||||
|
base_iterator last,
|
||||||
|
difference_type stride)
|
||||||
|
: m_it(it)
|
||||||
|
, m_last(last)
|
||||||
|
, m_stride(stride)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
strided_iterator(
|
||||||
|
const strided_iterator<OtherIterator, Category>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator,
|
||||||
|
base_iterator
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
: m_it(other.base())
|
||||||
|
, m_last(other.base_end())
|
||||||
|
, m_stride(other.get_stride())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
base_iterator base() const
|
||||||
|
{
|
||||||
|
return m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_iterator base_end() const
|
||||||
|
{
|
||||||
|
return m_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type get_stride() const
|
||||||
|
{
|
||||||
|
return m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
for (difference_type i = 0;
|
||||||
|
(m_it != m_last) && (i < m_stride); ++i)
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reference dereference() const
|
||||||
|
{
|
||||||
|
return *m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
bool equal(
|
||||||
|
const strided_iterator<OtherIterator, Category>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator,
|
||||||
|
base_iterator
|
||||||
|
>::type* = 0) const
|
||||||
|
{
|
||||||
|
return m_it == other.m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_iterator m_it;
|
||||||
|
base_iterator m_last;
|
||||||
|
difference_type m_stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
// strided_iterator for wrapping a bidirectional iterator
|
||||||
|
template<class BaseIterator>
|
||||||
|
class strided_iterator<BaseIterator, bidirectional_traversal_tag>
|
||||||
|
: public iterator_facade<
|
||||||
|
strided_iterator<BaseIterator, bidirectional_traversal_tag>
|
||||||
|
, typename iterator_value<BaseIterator>::type
|
||||||
|
, bidirectional_traversal_tag
|
||||||
|
, typename iterator_reference<BaseIterator>::type
|
||||||
|
, typename iterator_difference<BaseIterator>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
friend class ::boost::iterator_core_access;
|
||||||
|
|
||||||
|
typedef iterator_facade<
|
||||||
|
strided_iterator<BaseIterator, bidirectional_traversal_tag>
|
||||||
|
, typename iterator_value<BaseIterator>::type
|
||||||
|
, bidirectional_traversal_tag
|
||||||
|
, typename iterator_reference<BaseIterator>::type
|
||||||
|
, typename iterator_difference<BaseIterator>::type
|
||||||
|
> super_t;
|
||||||
|
public:
|
||||||
|
typedef typename super_t::difference_type difference_type;
|
||||||
|
typedef typename super_t::reference reference;
|
||||||
|
typedef BaseIterator base_iterator;
|
||||||
|
typedef typename boost::make_unsigned<difference_type>::type
|
||||||
|
size_type;
|
||||||
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
strided_iterator()
|
||||||
|
: m_it()
|
||||||
|
, m_offset()
|
||||||
|
, m_index()
|
||||||
|
, m_stride()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
strided_iterator(base_iterator it,
|
||||||
|
size_type index,
|
||||||
|
difference_type stride)
|
||||||
|
: m_it(it)
|
||||||
|
, m_offset()
|
||||||
|
, m_index(index)
|
||||||
|
, m_stride(stride)
|
||||||
|
{
|
||||||
|
if (stride && ((m_index % stride) != 0))
|
||||||
|
m_index += (stride - (m_index % stride));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
strided_iterator(
|
||||||
|
const strided_iterator<
|
||||||
|
OtherIterator,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator,
|
||||||
|
base_iterator
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
: m_it(other.base())
|
||||||
|
, m_offset(other.get_offset())
|
||||||
|
, m_index(other.get_index())
|
||||||
|
, m_stride(other.get_stride())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
base_iterator base() const
|
||||||
|
{
|
||||||
|
return m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type get_offset() const
|
||||||
|
{
|
||||||
|
return m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type get_index() const
|
||||||
|
{
|
||||||
|
return m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type get_stride() const
|
||||||
|
{
|
||||||
|
return m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
m_offset += m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
m_offset -= m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference dereference() const
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
return *m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() const
|
||||||
|
{
|
||||||
|
std::advance(m_it, m_offset);
|
||||||
|
m_index += m_offset;
|
||||||
|
m_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
bool equal(
|
||||||
|
const strided_iterator<
|
||||||
|
OtherIterator,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator,
|
||||||
|
base_iterator
|
||||||
|
>::type* = 0) const
|
||||||
|
{
|
||||||
|
return (m_index + m_offset) ==
|
||||||
|
(other.get_index() + other.get_offset());
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable base_iterator m_it;
|
||||||
|
mutable difference_type m_offset;
|
||||||
|
mutable size_type m_index;
|
||||||
|
difference_type m_stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
// strided_iterator implementation for wrapping a random access iterator
|
||||||
|
template<class BaseIterator>
|
||||||
|
class strided_iterator<BaseIterator, random_access_traversal_tag>
|
||||||
|
: public iterator_facade<
|
||||||
|
strided_iterator<BaseIterator, random_access_traversal_tag>
|
||||||
|
, typename iterator_value<BaseIterator>::type
|
||||||
|
, random_access_traversal_tag
|
||||||
|
, typename iterator_reference<BaseIterator>::type
|
||||||
|
, typename iterator_difference<BaseIterator>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
friend class ::boost::iterator_core_access;
|
||||||
|
|
||||||
|
typedef iterator_facade<
|
||||||
|
strided_iterator<BaseIterator, random_access_traversal_tag>
|
||||||
|
, typename iterator_value<BaseIterator>::type
|
||||||
|
, random_access_traversal_tag
|
||||||
|
, typename iterator_reference<BaseIterator>::type
|
||||||
|
, typename iterator_difference<BaseIterator>::type
|
||||||
|
> super_t;
|
||||||
|
public:
|
||||||
|
typedef typename super_t::difference_type difference_type;
|
||||||
|
typedef typename super_t::reference reference;
|
||||||
|
typedef BaseIterator base_iterator;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
strided_iterator()
|
||||||
|
: m_it()
|
||||||
|
, m_first()
|
||||||
|
, m_index(0)
|
||||||
|
, m_stride()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
strided_iterator(
|
||||||
|
base_iterator first,
|
||||||
|
base_iterator it,
|
||||||
|
difference_type stride
|
||||||
|
)
|
||||||
|
: m_it(it)
|
||||||
|
, m_first(first)
|
||||||
|
, m_index(stride ? (it - first) : difference_type())
|
||||||
|
, m_stride(stride)
|
||||||
|
{
|
||||||
|
if (stride && ((m_index % stride) != 0))
|
||||||
|
m_index += (stride - (m_index % stride));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
strided_iterator(
|
||||||
|
const strided_iterator<
|
||||||
|
OtherIterator,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator,
|
||||||
|
base_iterator
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
: m_it(other.base())
|
||||||
|
, m_first(other.base_begin())
|
||||||
|
, m_index(other.get_index())
|
||||||
|
, m_stride(other.get_stride())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
base_iterator base_begin() const
|
||||||
|
{
|
||||||
|
return m_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_iterator base() const
|
||||||
|
{
|
||||||
|
return m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type get_stride() const
|
||||||
|
{
|
||||||
|
return m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type get_index() const
|
||||||
|
{
|
||||||
|
return m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
m_index += m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
m_index -= m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance(difference_type offset)
|
||||||
|
{
|
||||||
|
m_index += (m_stride * offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation detail: only update the actual underlying iterator
|
||||||
|
// at the point of dereference. This is done so that the increment
|
||||||
|
// and decrement can overshoot the valid sequence as is required
|
||||||
|
// by striding. Since we can do all comparisons just with the index
|
||||||
|
// simply, and all dereferences must be within the valid range.
|
||||||
|
void update() const
|
||||||
|
{
|
||||||
|
m_it = m_first + m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
difference_type distance_to(
|
||||||
|
const strided_iterator<
|
||||||
|
OtherIterator,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator, base_iterator>::type* = 0) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT((other.m_index - m_index) % m_stride == difference_type());
|
||||||
|
return (other.m_index - m_index) / m_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
bool equal(
|
||||||
|
const strided_iterator<
|
||||||
|
OtherIterator,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>& other,
|
||||||
|
typename enable_if_convertible<
|
||||||
|
OtherIterator, base_iterator>::type* = 0) const
|
||||||
|
{
|
||||||
|
return m_index == other.m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference dereference() const
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
return *m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable base_iterator m_it;
|
||||||
|
base_iterator m_first;
|
||||||
|
difference_type m_index;
|
||||||
|
difference_type m_stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>
|
||||||
|
make_begin_strided_iterator(
|
||||||
|
Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
forward_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>(boost::begin(rng), boost::end(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>
|
||||||
|
make_begin_strided_iterator(
|
||||||
|
const Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
forward_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>(boost::begin(rng), boost::end(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>
|
||||||
|
make_end_strided_iterator(
|
||||||
|
Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
forward_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>(boost::end(rng), boost::end(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>
|
||||||
|
make_end_strided_iterator(
|
||||||
|
const Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
forward_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
forward_traversal_tag
|
||||||
|
>(boost::end(rng), boost::end(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>
|
||||||
|
make_begin_strided_iterator(
|
||||||
|
Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
bidirectional_traversal_tag)
|
||||||
|
{
|
||||||
|
typedef typename range_difference<Rng>::type difference_type;
|
||||||
|
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>(boost::begin(rng), difference_type(), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>
|
||||||
|
make_begin_strided_iterator(
|
||||||
|
const Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
bidirectional_traversal_tag)
|
||||||
|
{
|
||||||
|
typedef typename range_difference<const Rng>::type difference_type;
|
||||||
|
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>(boost::begin(rng), difference_type(), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>
|
||||||
|
make_end_strided_iterator(
|
||||||
|
Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
bidirectional_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>(boost::end(rng), boost::size(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>
|
||||||
|
make_end_strided_iterator(
|
||||||
|
const Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
bidirectional_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>(boost::end(rng), boost::size(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>
|
||||||
|
make_begin_strided_iterator(
|
||||||
|
Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
random_access_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>(boost::begin(rng), boost::begin(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>
|
||||||
|
make_begin_strided_iterator(
|
||||||
|
const Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
random_access_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>(boost::begin(rng), boost::begin(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>
|
||||||
|
make_end_strided_iterator(
|
||||||
|
Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
random_access_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>(boost::begin(rng), boost::end(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference> inline
|
||||||
|
strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>
|
||||||
|
make_end_strided_iterator(
|
||||||
|
const Rng& rng,
|
||||||
|
Difference stride,
|
||||||
|
random_access_traversal_tag)
|
||||||
|
{
|
||||||
|
return strided_iterator<
|
||||||
|
typename range_iterator<const Rng>::type,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>(boost::begin(rng), boost::end(rng), stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Rng,
|
||||||
|
class Category =
|
||||||
|
typename iterator_traversal<
|
||||||
|
typename range_iterator<Rng>::type
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
class strided_range
|
||||||
|
: public iterator_range<
|
||||||
|
range_detail::strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
Category
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef range_detail::strided_iterator<
|
||||||
|
typename range_iterator<Rng>::type,
|
||||||
|
Category
|
||||||
|
> iter_type;
|
||||||
|
typedef iterator_range<iter_type> super_t;
|
||||||
|
public:
|
||||||
|
template<class Difference>
|
||||||
|
strided_range(Difference stride, Rng& rng)
|
||||||
|
: super_t(
|
||||||
|
range_detail::make_begin_strided_iterator(
|
||||||
|
rng, stride,
|
||||||
|
typename iterator_traversal<
|
||||||
|
typename range_iterator<Rng>::type
|
||||||
|
>::type()),
|
||||||
|
range_detail::make_end_strided_iterator(
|
||||||
|
rng, stride,
|
||||||
|
typename iterator_traversal<
|
||||||
|
typename range_iterator<Rng>::type
|
||||||
|
>::type()))
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( stride >= 0 );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Difference>
|
||||||
|
class strided_holder : public holder<Difference>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit strided_holder(Difference value)
|
||||||
|
: holder<Difference>(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Rng, class Difference>
|
||||||
|
inline strided_range<Rng>
|
||||||
|
operator|(Rng& rng, const strided_holder<Difference>& stride)
|
||||||
|
{
|
||||||
|
return strided_range<Rng>(stride.val, rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rng, class Difference>
|
||||||
|
inline strided_range<const Rng>
|
||||||
|
operator|(const Rng& rng, const strided_holder<Difference>& stride)
|
||||||
|
{
|
||||||
|
return strided_range<const Rng>(stride.val, rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 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'
|
||||||
|
|
||||||
|
#endif
|
137
boost/range/adaptor/tokenized.hpp
Normal file
137
boost/range/adaptor/tokenized.hpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen, Neil Groves 2006. 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_TOKENIZED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
|
||||||
|
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class R >
|
||||||
|
struct tokenized_range :
|
||||||
|
public boost::iterator_range<
|
||||||
|
boost::regex_token_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef
|
||||||
|
boost::regex_token_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<R>::type
|
||||||
|
>
|
||||||
|
regex_iter;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type
|
||||||
|
regex_type;
|
||||||
|
|
||||||
|
typedef boost::iterator_range<regex_iter>
|
||||||
|
base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template< class Regex, class Submatch, class Flag >
|
||||||
|
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() )
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T, class U, class V >
|
||||||
|
struct regex_holder
|
||||||
|
{
|
||||||
|
T re;
|
||||||
|
U sub;
|
||||||
|
V f;
|
||||||
|
|
||||||
|
regex_holder( const T& rex, const U& subm, V flag ) :
|
||||||
|
re(rex), sub(subm), f(flag)
|
||||||
|
{ }
|
||||||
|
private:
|
||||||
|
// Not assignable
|
||||||
|
void operator=(const regex_holder&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regex_forwarder
|
||||||
|
{
|
||||||
|
template< class Regex >
|
||||||
|
regex_holder<Regex,int,regex_constants::match_flag_type>
|
||||||
|
operator()( const Regex& re,
|
||||||
|
int submatch = 0,
|
||||||
|
regex_constants::match_flag_type f =
|
||||||
|
regex_constants::match_default ) const
|
||||||
|
{
|
||||||
|
return regex_holder<Regex,int,
|
||||||
|
regex_constants::match_flag_type>( re, submatch, f );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Regex, class Submatch >
|
||||||
|
regex_holder<Regex,Submatch,regex_constants::match_flag_type>
|
||||||
|
operator()( const Regex& re,
|
||||||
|
const Submatch& sub,
|
||||||
|
regex_constants::match_flag_type f =
|
||||||
|
regex_constants::match_default ) const
|
||||||
|
{
|
||||||
|
return regex_holder<Regex,Submatch,
|
||||||
|
regex_constants::match_flag_type>( re, sub, f );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class BidirectionalRng, class R, class S, class F >
|
||||||
|
inline tokenized_range<BidirectionalRng>
|
||||||
|
operator|( BidirectionalRng& r,
|
||||||
|
const regex_holder<R,S,F>& f )
|
||||||
|
{
|
||||||
|
return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class BidirectionalRng, class R, class S, class F >
|
||||||
|
inline tokenized_range<const BidirectionalRng>
|
||||||
|
operator|( const BidirectionalRng& r,
|
||||||
|
const regex_holder<R,S,F>& f )
|
||||||
|
{
|
||||||
|
return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::tokenized_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::regex_forwarder tokenized =
|
||||||
|
range_detail::regex_forwarder();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class BidirectionalRange, class Regex, class Submatch, class Flag>
|
||||||
|
inline tokenized_range<BidirectionalRange>
|
||||||
|
tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
|
||||||
|
{
|
||||||
|
return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class BidirectionalRange, class Regex, class Submatch, class Flag>
|
||||||
|
inline tokenized_range<const BidirectionalRange>
|
||||||
|
tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
|
||||||
|
{
|
||||||
|
return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
137
boost/range/adaptor/transformed.hpp
Normal file
137
boost/range/adaptor/transformed.hpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// 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_TRANSFORMED_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/argument_fwd.hpp>
|
||||||
|
#include <boost/range/detail/default_constructible_unary_fn.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/utility/result_of.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
// A type generator to produce the transform_iterator type conditionally
|
||||||
|
// including a wrapped predicate as appropriate.
|
||||||
|
template<typename P, typename It>
|
||||||
|
struct transform_iterator_gen
|
||||||
|
{
|
||||||
|
typedef transform_iterator<
|
||||||
|
typename default_constructible_unary_fn_gen<
|
||||||
|
P,
|
||||||
|
typename transform_iterator<P, It>::reference
|
||||||
|
>::type,
|
||||||
|
It
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class F, class R >
|
||||||
|
struct transformed_range :
|
||||||
|
public boost::iterator_range<
|
||||||
|
typename transform_iterator_gen<
|
||||||
|
F, typename range_iterator<R>::type>::type>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef typename transform_iterator_gen<
|
||||||
|
F, typename range_iterator<R>::type>::type transform_iter_t;
|
||||||
|
|
||||||
|
typedef boost::iterator_range<transform_iter_t> base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename default_constructible_unary_fn_gen<
|
||||||
|
F,
|
||||||
|
typename transform_iterator<
|
||||||
|
F,
|
||||||
|
typename range_iterator<R>::type
|
||||||
|
>::reference
|
||||||
|
>::type transform_fn_type;
|
||||||
|
|
||||||
|
typedef R source_range_type;
|
||||||
|
|
||||||
|
transformed_range(transform_fn_type f, R& r)
|
||||||
|
: base(transform_iter_t(boost::begin(r), f),
|
||||||
|
transform_iter_t(boost::end(r), f))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct transform_holder : holder<T>
|
||||||
|
{
|
||||||
|
transform_holder( T r ) : holder<T>(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class SinglePassRange, class UnaryFunction >
|
||||||
|
inline transformed_range<UnaryFunction,SinglePassRange>
|
||||||
|
operator|( SinglePassRange& r,
|
||||||
|
const transform_holder<UnaryFunction>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return transformed_range<UnaryFunction,SinglePassRange>( f.val, r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassRange, class UnaryFunction >
|
||||||
|
inline transformed_range<UnaryFunction, const SinglePassRange>
|
||||||
|
operator|( const SinglePassRange& r,
|
||||||
|
const transform_holder<UnaryFunction>& f )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return transformed_range<UnaryFunction, const SinglePassRange>(
|
||||||
|
f.val, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::transformed_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::forwarder<range_detail::transform_holder>
|
||||||
|
transformed =
|
||||||
|
range_detail::forwarder<range_detail::transform_holder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class UnaryFunction, class SinglePassRange>
|
||||||
|
inline transformed_range<UnaryFunction, SinglePassRange>
|
||||||
|
transform(SinglePassRange& rng, UnaryFunction fn)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
return transformed_range<UnaryFunction, SinglePassRange>(fn, rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class UnaryFunction, class SinglePassRange>
|
||||||
|
inline transformed_range<UnaryFunction, const SinglePassRange>
|
||||||
|
transform(const SinglePassRange& rng, UnaryFunction fn)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return transformed_range<UnaryFunction, const SinglePassRange>(
|
||||||
|
fn, rng);
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
196
boost/range/adaptor/type_erased.hpp
Normal file
196
boost/range/adaptor/type_erased.hpp
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
// 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_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/reference.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
#include <boost/range/any_range.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
template<
|
||||||
|
class Value = use_default
|
||||||
|
, class Traversal = use_default
|
||||||
|
, class Reference = use_default
|
||||||
|
, class Difference = use_default
|
||||||
|
, class Buffer = use_default
|
||||||
|
>
|
||||||
|
struct type_erased
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class SinglePassRange
|
||||||
|
, class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
typename any_range_type_generator<
|
||||||
|
SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type
|
||||||
|
operator|(SinglePassRange& rng,
|
||||||
|
type_erased<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
typedef typename any_range_type_generator<
|
||||||
|
SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type range_type;
|
||||||
|
return range_type(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
class SinglePassRange
|
||||||
|
, class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
typename any_range_type_generator<
|
||||||
|
const SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type
|
||||||
|
operator|(const SinglePassRange& rng,
|
||||||
|
type_erased<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
typedef typename any_range_type_generator<
|
||||||
|
const SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type range_type;
|
||||||
|
return range_type(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
class SinglePassRange
|
||||||
|
, class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
typename any_range_type_generator<
|
||||||
|
SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type
|
||||||
|
type_erase(SinglePassRange& rng
|
||||||
|
, type_erased<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> = type_erased<>()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<SinglePassRange>));
|
||||||
|
|
||||||
|
typedef typename any_range_type_generator<
|
||||||
|
SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type range_type;
|
||||||
|
|
||||||
|
return range_type(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
class SinglePassRange
|
||||||
|
, class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
typename any_range_type_generator<
|
||||||
|
const SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type
|
||||||
|
type_erase(const SinglePassRange& rng
|
||||||
|
, type_erased<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> = type_erased<>()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
typedef typename any_range_type_generator<
|
||||||
|
const SinglePassRange
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type range_type;
|
||||||
|
|
||||||
|
return range_type(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
97
boost/range/adaptor/uniqued.hpp
Normal file
97
boost/range/adaptor/uniqued.hpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// 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_UNIQUED_IMPL_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/adjacent_filtered.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
struct unique_forwarder { };
|
||||||
|
|
||||||
|
struct unique_not_equal_to
|
||||||
|
{
|
||||||
|
typedef bool result_type;
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
bool operator()( const T& l, const T& r ) const
|
||||||
|
{
|
||||||
|
return !(l == r);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class ForwardRng>
|
||||||
|
class uniqued_range : public adjacent_filtered_range<unique_not_equal_to, ForwardRng, true>
|
||||||
|
{
|
||||||
|
typedef adjacent_filtered_range<unique_not_equal_to, ForwardRng, true> base;
|
||||||
|
public:
|
||||||
|
explicit uniqued_range(ForwardRng& rng)
|
||||||
|
: base(unique_not_equal_to(), rng)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class ForwardRng >
|
||||||
|
inline uniqued_range<ForwardRng>
|
||||||
|
operator|( ForwardRng& r,
|
||||||
|
unique_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
|
||||||
|
return uniqued_range<ForwardRng>(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class ForwardRng >
|
||||||
|
inline uniqued_range<const ForwardRng>
|
||||||
|
operator|( const ForwardRng& r,
|
||||||
|
unique_forwarder )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
|
||||||
|
return uniqued_range<const ForwardRng>(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 'range_detail'
|
||||||
|
|
||||||
|
using range_detail::uniqued_range;
|
||||||
|
|
||||||
|
namespace adaptors
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const range_detail::unique_forwarder uniqued =
|
||||||
|
range_detail::unique_forwarder();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline uniqued_range<ForwardRange>
|
||||||
|
unique(ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return uniqued_range<ForwardRange>(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline uniqued_range<const ForwardRange>
|
||||||
|
unique(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
ForwardRangeConcept<const ForwardRange>));
|
||||||
|
|
||||||
|
return uniqued_range<const ForwardRange>(rng);
|
||||||
|
}
|
||||||
|
} // 'adaptors'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
31
boost/range/adaptors.hpp
Normal file
31
boost/range/adaptors.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2007.
|
||||||
|
// Copyright Thorsten Ottosen 2006.
|
||||||
|
// 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_ADAPTORS_HPP
|
||||||
|
#define BOOST_RANGE_ADAPTORS_HPP
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/adjacent_filtered.hpp>
|
||||||
|
#include <boost/range/adaptor/copied.hpp>
|
||||||
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
|
#include <boost/range/adaptor/formatted.hpp>
|
||||||
|
#include <boost/range/adaptor/indexed.hpp>
|
||||||
|
#include <boost/range/adaptor/indirected.hpp>
|
||||||
|
#include <boost/range/adaptor/map.hpp>
|
||||||
|
#include <boost/range/adaptor/replaced.hpp>
|
||||||
|
#include <boost/range/adaptor/replaced_if.hpp>
|
||||||
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
#include <boost/range/adaptor/sliced.hpp>
|
||||||
|
#include <boost/range/adaptor/strided.hpp>
|
||||||
|
#include <boost/range/adaptor/tokenized.hpp>
|
||||||
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
|
#include <boost/range/adaptor/uniqued.hpp>
|
||||||
|
|
||||||
|
#endif
|
104
boost/range/algorithm.hpp
Normal file
104
boost/range/algorithm.hpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file algorithm.hpp
|
||||||
|
/// Includes the range-based versions of the algorithms in the
|
||||||
|
/// C++ standard header file <algorithm>
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Copyright 2009 Neil Groves.
|
||||||
|
// Distributed under 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)
|
||||||
|
//
|
||||||
|
// Acknowledgements:
|
||||||
|
// This code uses combinations of ideas, techniques and code snippets
|
||||||
|
// from: Thorsten Ottosen, Eric Niebler, Jeremy Siek,
|
||||||
|
// and Vladimir Prus'
|
||||||
|
//
|
||||||
|
// The original mutating algorithms that served as the first version
|
||||||
|
// were originally written by Vladimir Prus'
|
||||||
|
// <ghost@cs.msu.su> code from Boost Wiki
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
|
||||||
|
#define BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
|
||||||
|
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
#include <boost/next_prior.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// Non-mutating algorithms
|
||||||
|
#include <boost/range/algorithm/adjacent_find.hpp>
|
||||||
|
#include <boost/range/algorithm/count.hpp>
|
||||||
|
#include <boost/range/algorithm/count_if.hpp>
|
||||||
|
#include <boost/range/algorithm/equal.hpp>
|
||||||
|
#include <boost/range/algorithm/for_each.hpp>
|
||||||
|
#include <boost/range/algorithm/find.hpp>
|
||||||
|
#include <boost/range/algorithm/find_end.hpp>
|
||||||
|
#include <boost/range/algorithm/find_first_of.hpp>
|
||||||
|
#include <boost/range/algorithm/find_if.hpp>
|
||||||
|
#include <boost/range/algorithm/lexicographical_compare.hpp>
|
||||||
|
#include <boost/range/algorithm/mismatch.hpp>
|
||||||
|
#include <boost/range/algorithm/search.hpp>
|
||||||
|
#include <boost/range/algorithm/search_n.hpp>
|
||||||
|
|
||||||
|
// Mutating algorithms
|
||||||
|
#include <boost/range/algorithm/copy.hpp>
|
||||||
|
#include <boost/range/algorithm/copy_backward.hpp>
|
||||||
|
#include <boost/range/algorithm/fill.hpp>
|
||||||
|
#include <boost/range/algorithm/fill_n.hpp>
|
||||||
|
#include <boost/range/algorithm/generate.hpp>
|
||||||
|
#include <boost/range/algorithm/inplace_merge.hpp>
|
||||||
|
#include <boost/range/algorithm/merge.hpp>
|
||||||
|
#include <boost/range/algorithm/nth_element.hpp>
|
||||||
|
#include <boost/range/algorithm/partial_sort.hpp>
|
||||||
|
#include <boost/range/algorithm/partial_sort_copy.hpp>
|
||||||
|
#include <boost/range/algorithm/partition.hpp>
|
||||||
|
#include <boost/range/algorithm/random_shuffle.hpp>
|
||||||
|
#include <boost/range/algorithm/remove.hpp>
|
||||||
|
#include <boost/range/algorithm/remove_copy.hpp>
|
||||||
|
#include <boost/range/algorithm/remove_copy_if.hpp>
|
||||||
|
#include <boost/range/algorithm/remove_if.hpp>
|
||||||
|
#include <boost/range/algorithm/replace.hpp>
|
||||||
|
#include <boost/range/algorithm/replace_copy.hpp>
|
||||||
|
#include <boost/range/algorithm/replace_copy_if.hpp>
|
||||||
|
#include <boost/range/algorithm/replace_if.hpp>
|
||||||
|
#include <boost/range/algorithm/reverse.hpp>
|
||||||
|
#include <boost/range/algorithm/reverse_copy.hpp>
|
||||||
|
#include <boost/range/algorithm/rotate.hpp>
|
||||||
|
#include <boost/range/algorithm/rotate_copy.hpp>
|
||||||
|
#include <boost/range/algorithm/sort.hpp>
|
||||||
|
#include <boost/range/algorithm/stable_partition.hpp>
|
||||||
|
#include <boost/range/algorithm/stable_sort.hpp>
|
||||||
|
#include <boost/range/algorithm/transform.hpp>
|
||||||
|
#include <boost/range/algorithm/unique.hpp>
|
||||||
|
#include <boost/range/algorithm/unique_copy.hpp>
|
||||||
|
|
||||||
|
// Binary search
|
||||||
|
#include <boost/range/algorithm/binary_search.hpp>
|
||||||
|
#include <boost/range/algorithm/equal_range.hpp>
|
||||||
|
#include <boost/range/algorithm/lower_bound.hpp>
|
||||||
|
#include <boost/range/algorithm/upper_bound.hpp>
|
||||||
|
|
||||||
|
// Set operations of sorted ranges
|
||||||
|
#include <boost/range/algorithm/set_algorithm.hpp>
|
||||||
|
|
||||||
|
// Heap operations
|
||||||
|
#include <boost/range/algorithm/heap_algorithm.hpp>
|
||||||
|
|
||||||
|
// Minimum and Maximum
|
||||||
|
#include <boost/range/algorithm/max_element.hpp>
|
||||||
|
#include <boost/range/algorithm/min_element.hpp>
|
||||||
|
|
||||||
|
// Permutations
|
||||||
|
#include <boost/range/algorithm/permutation.hpp>
|
||||||
|
|
||||||
|
#endif // include guard
|
||||||
|
|
125
boost/range/algorithm/adjacent_find.hpp
Normal file
125
boost/range/algorithm/adjacent_find.hpp
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function adjacent_find
|
||||||
|
///
|
||||||
|
/// range-based version of the adjacent_find std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< typename ForwardRange >
|
||||||
|
inline typename range_iterator<ForwardRange>::type
|
||||||
|
adjacent_find(ForwardRange & rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return std::adjacent_find(boost::begin(rng),boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< typename ForwardRange >
|
||||||
|
inline typename range_iterator<const ForwardRange>::type
|
||||||
|
adjacent_find(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return std::adjacent_find(boost::begin(rng),boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< typename ForwardRange, typename BinaryPredicate >
|
||||||
|
inline typename range_iterator<ForwardRange>::type
|
||||||
|
adjacent_find(ForwardRange & rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
typename range_value<ForwardRange>::type,
|
||||||
|
typename range_value<ForwardRange>::type>));
|
||||||
|
return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< typename ForwardRange, typename BinaryPredicate >
|
||||||
|
inline typename range_iterator<const ForwardRange>::type
|
||||||
|
adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
typename range_value<const ForwardRange>::type,
|
||||||
|
typename range_value<const ForwardRange>::type>));
|
||||||
|
return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, typename ForwardRange >
|
||||||
|
inline typename range_return<ForwardRange,re>::type
|
||||||
|
adjacent_find(ForwardRange & rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, typename ForwardRange >
|
||||||
|
inline typename range_return<const ForwardRange,re>::type
|
||||||
|
adjacent_find(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
|
||||||
|
inline typename range_return<ForwardRange,re>::type
|
||||||
|
adjacent_find(ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
typename range_value<ForwardRange>::type,
|
||||||
|
typename range_value<ForwardRange>::type>));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
|
||||||
|
inline typename range_return<const ForwardRange,re>::type
|
||||||
|
adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::adjacent_find;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
49
boost/range/algorithm/binary_search.hpp
Normal file
49
boost/range/algorithm/binary_search.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function binary_search
|
||||||
|
///
|
||||||
|
/// range-based version of the binary_search std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class ForwardRange, class Value>
|
||||||
|
inline bool binary_search(const ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::binary_search(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class Value, class BinaryPredicate>
|
||||||
|
inline bool binary_search(const ForwardRange& rng, const Value& val,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::binary_search(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::binary_search;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
41
boost/range/algorithm/copy.hpp
Normal file
41
boost/range/algorithm/copy.hpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function copy
|
||||||
|
///
|
||||||
|
/// range-based version of the copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre OutputIterator is a model of the OutputIteratorConcept
|
||||||
|
template< class SinglePassRange, class OutputIterator >
|
||||||
|
inline OutputIterator copy(const SinglePassRange& rng, OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::copy(boost::begin(rng),boost::end(rng),out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
43
boost/range/algorithm/copy_backward.hpp
Normal file
43
boost/range/algorithm/copy_backward.hpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function copy_backward
|
||||||
|
///
|
||||||
|
/// range-based version of the copy_backwards std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
/// \pre BidirectionalTraversalWriteableIterator is a model of the BidirectionalIteratorConcept
|
||||||
|
/// \pre BidirectionalTraversalWriteableIterator is a model of the WriteableIteratorConcept
|
||||||
|
template< class BidirectionalRange, class BidirectionalTraversalWriteableIterator >
|
||||||
|
inline BidirectionalTraversalWriteableIterator
|
||||||
|
copy_backward(const BidirectionalRange& rng,
|
||||||
|
BidirectionalTraversalWriteableIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::copy_backward(boost::begin(rng), boost::end(rng), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::copy_backward;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
50
boost/range/algorithm/count.hpp
Normal file
50
boost/range/algorithm/count.hpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_COUNT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function count
|
||||||
|
///
|
||||||
|
/// range-based version of the count std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
template< class SinglePassRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
|
||||||
|
count(SinglePassRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
return std::count(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange const>::type
|
||||||
|
count(const SinglePassRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::count(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::count;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
51
boost/range/algorithm/count_if.hpp
Normal file
51
boost/range/algorithm/count_if.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_COUNT_IF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function count_if
|
||||||
|
///
|
||||||
|
/// range-based version of the count_if std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
|
||||||
|
template< class SinglePassRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME boost::range_difference<SinglePassRange>::type
|
||||||
|
count_if(SinglePassRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
return std::count_if(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME boost::range_difference<const SinglePassRange>::type
|
||||||
|
count_if(const SinglePassRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::count_if(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::count_if;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
200
boost/range/algorithm/equal.hpp
Normal file
200
boost/range/algorithm/equal.hpp
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009.
|
||||||
|
// 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_ALGORITHM_EQUAL_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
// An implementation of equality comparison that is optimized for iterator
|
||||||
|
// traversal categories less than RandomAccessTraversal.
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2,
|
||||||
|
class IteratorCategoryTag1,
|
||||||
|
class IteratorCategoryTag2 >
|
||||||
|
inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2,
|
||||||
|
IteratorCategoryTag1,
|
||||||
|
IteratorCategoryTag2 )
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
// If we have reached the end of the left range then this is
|
||||||
|
// the end of the loop. They are equal if and only if we have
|
||||||
|
// simultaneously reached the end of the right range.
|
||||||
|
if (first1 == last1)
|
||||||
|
return first2 == last2;
|
||||||
|
|
||||||
|
// If we have reached the end of the right range at this line
|
||||||
|
// it indicates that the right range is shorter than the left
|
||||||
|
// and hence the result is false.
|
||||||
|
if (first2 == last2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// continue looping if and only if the values are equal
|
||||||
|
if (*first1 != *first2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++first1;
|
||||||
|
++first2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reaching this line in the algorithm indicates that a value
|
||||||
|
// inequality has been detected.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2,
|
||||||
|
class IteratorCategoryTag1,
|
||||||
|
class IteratorCategoryTag2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2,
|
||||||
|
BinaryPredicate pred,
|
||||||
|
IteratorCategoryTag1,
|
||||||
|
IteratorCategoryTag2 )
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
// If we have reached the end of the left range then this is
|
||||||
|
// the end of the loop. They are equal if and only if we have
|
||||||
|
// simultaneously reached the end of the right range.
|
||||||
|
if (first1 == last1)
|
||||||
|
return first2 == last2;
|
||||||
|
|
||||||
|
// If we have reached the end of the right range at this line
|
||||||
|
// it indicates that the right range is shorter than the left
|
||||||
|
// and hence the result is false.
|
||||||
|
if (first2 == last2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// continue looping if and only if the values are equal
|
||||||
|
if (!pred(*first1, *first2))
|
||||||
|
break;
|
||||||
|
|
||||||
|
++first1;
|
||||||
|
++first2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reaching this line in the algorithm indicates that a value
|
||||||
|
// inequality has been detected.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An implementation of equality comparison that is optimized for
|
||||||
|
// random access iterators.
|
||||||
|
template< class RandomAccessTraversalReadableIterator1,
|
||||||
|
class RandomAccessTraversalReadableIterator2 >
|
||||||
|
inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
|
||||||
|
RandomAccessTraversalReadableIterator1 last1,
|
||||||
|
RandomAccessTraversalReadableIterator2 first2,
|
||||||
|
RandomAccessTraversalReadableIterator2 last2,
|
||||||
|
std::random_access_iterator_tag,
|
||||||
|
std::random_access_iterator_tag )
|
||||||
|
{
|
||||||
|
return ((last1 - first1) == (last2 - first2))
|
||||||
|
&& std::equal(first1, last1, first2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class RandomAccessTraversalReadableIterator1,
|
||||||
|
class RandomAccessTraversalReadableIterator2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
|
||||||
|
RandomAccessTraversalReadableIterator1 last1,
|
||||||
|
RandomAccessTraversalReadableIterator2 first2,
|
||||||
|
RandomAccessTraversalReadableIterator2 last2,
|
||||||
|
BinaryPredicate pred,
|
||||||
|
std::random_access_iterator_tag,
|
||||||
|
std::random_access_iterator_tag )
|
||||||
|
{
|
||||||
|
return ((last1 - first1) == (last2 - first2))
|
||||||
|
&& std::equal(first1, last1, first2, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2 >
|
||||||
|
inline bool equal( SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2 )
|
||||||
|
{
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
|
||||||
|
|
||||||
|
return equal_impl(first1, last1, first2, last2, tag1, tag2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline bool equal( SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2,
|
||||||
|
BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
|
||||||
|
BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
|
||||||
|
|
||||||
|
return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function equal
|
||||||
|
///
|
||||||
|
/// range-based version of the equal std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::equal(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||||
|
inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
|
||||||
|
BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::equal(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2),
|
||||||
|
pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using ::boost::range::equal;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
80
boost/range/algorithm/equal_range.hpp
Normal file
80
boost/range/algorithm/equal_range.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function equal_range
|
||||||
|
///
|
||||||
|
/// range-based version of the equal_range std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre SortPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class ForwardRange, class Value>
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
|
||||||
|
>
|
||||||
|
equal_range(ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::equal_range(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class Value>
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
|
||||||
|
>
|
||||||
|
equal_range(const ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::equal_range(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class Value, class SortPredicate>
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
|
||||||
|
>
|
||||||
|
equal_range(ForwardRange& rng, const Value& val, SortPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class Value, class SortPredicate>
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
|
||||||
|
>
|
||||||
|
equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::equal_range;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
49
boost/range/algorithm/fill.hpp
Normal file
49
boost/range/algorithm/fill.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FILL_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function fill
|
||||||
|
///
|
||||||
|
/// range-based version of the fill std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline ForwardRange& fill(ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
std::fill(boost::begin(rng), boost::end(rng), val);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline const ForwardRange& fill(const ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
std::fill(boost::begin(rng), boost::end(rng), val);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // include guard
|
53
boost/range/algorithm/fill_n.hpp
Normal file
53
boost/range/algorithm/fill_n.hpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FILL_N_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function fill_n
|
||||||
|
///
|
||||||
|
/// range-based version of the fill_n std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre n <= std::distance(boost::begin(rng), boost::end(rng))
|
||||||
|
template< class ForwardRange, class Size, class Value >
|
||||||
|
inline ForwardRange& fill_n(ForwardRange& rng, Size n, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
|
||||||
|
std::fill_n(boost::begin(rng), n, val);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Size, class Value >
|
||||||
|
inline const ForwardRange& fill_n(const ForwardRange& rng, Size n, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
|
||||||
|
std::fill_n(boost::begin(rng), n, val);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::fill_n;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
80
boost/range/algorithm/find.hpp
Normal file
80
boost/range/algorithm/find.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FIND_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function find
|
||||||
|
///
|
||||||
|
/// range-based version of the find std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
template< class SinglePassRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
|
||||||
|
>::type
|
||||||
|
find( SinglePassRange& rng, const Value& val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
return std::find(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
|
||||||
|
find( const SinglePassRange& rng, const Value& val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::find(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
|
||||||
|
>::type
|
||||||
|
find( SinglePassRange& rng, const Value& val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
return range_return<SinglePassRange,re>::
|
||||||
|
pack(std::find(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
|
||||||
|
find( const SinglePassRange& rng, const Value& val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return range_return<const SinglePassRange,re>::
|
||||||
|
pack(std::find(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::find;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // include guard
|
152
boost/range/algorithm/find_end.hpp
Normal file
152
boost/range/algorithm/find_end.hpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FIND_END_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function find_end
|
||||||
|
///
|
||||||
|
/// range-based version of the find_end std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange1 is a model of the ForwardRangeConcept
|
||||||
|
/// \pre ForwardRange2 is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type
|
||||||
|
>::type
|
||||||
|
find_end(ForwardRange1 & rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_end(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator< const ForwardRange1 >::type
|
||||||
|
find_end(const ForwardRange1 & rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_end(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
|
||||||
|
>::type
|
||||||
|
find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_end(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
|
||||||
|
find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_end(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
|
||||||
|
>::type
|
||||||
|
find_end(ForwardRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<ForwardRange1,re>::
|
||||||
|
pack(std::find_end(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2)),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
|
||||||
|
find_end(const ForwardRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<const ForwardRange1,re>::
|
||||||
|
pack(std::find_end(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2)),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
|
||||||
|
>::type
|
||||||
|
find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<ForwardRange1,re>::
|
||||||
|
pack(std::find_end(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
|
||||||
|
find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<const ForwardRange1,re>::
|
||||||
|
pack(std::find_end(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::find_end;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
155
boost/range/algorithm/find_first_of.hpp
Normal file
155
boost/range/algorithm/find_first_of.hpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function find_first_of
|
||||||
|
///
|
||||||
|
/// range-based version of the find_first_of std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre ForwardRange2 is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< class SinglePassRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
|
||||||
|
>::type
|
||||||
|
find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_first_of(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
|
||||||
|
find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_first_of(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
|
||||||
|
>::type
|
||||||
|
find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_first_of(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
|
||||||
|
find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return std::find_first_of(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range return overloads
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
|
||||||
|
>::type
|
||||||
|
find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<SinglePassRange1,re>::
|
||||||
|
pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2)),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
|
||||||
|
find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<const SinglePassRange1,re>::
|
||||||
|
pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2)),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange1, class ForwardRange2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange1>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
|
||||||
|
>::type
|
||||||
|
find_first_of(SinglePassRange1 & rng1, const ForwardRange2& rng2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<SinglePassRange1,re>::
|
||||||
|
pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange1, class ForwardRange2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
|
||||||
|
find_first_of(const SinglePassRange1 & rng1, const ForwardRange2& rng2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
|
||||||
|
return range_return<const SinglePassRange1,re>::
|
||||||
|
pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::find_first_of;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
81
boost/range/algorithm/find_if.hpp
Normal file
81
boost/range/algorithm/find_if.hpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FIND_IF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function find_if
|
||||||
|
///
|
||||||
|
/// range-based version of the find_if std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
|
||||||
|
template< class SinglePassRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
|
||||||
|
>::type
|
||||||
|
find_if( SinglePassRange& rng, UnaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
return std::find_if(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
|
||||||
|
find_if( const SinglePassRange& rng, UnaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::find_if(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<SinglePassRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
|
||||||
|
>::type
|
||||||
|
find_if( SinglePassRange& rng, UnaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
return range_return<SinglePassRange,re>::
|
||||||
|
pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class SinglePassRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
|
||||||
|
find_if( const SinglePassRange& rng, UnaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return range_return<const SinglePassRange,re>::
|
||||||
|
pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::find_if;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
110
boost/range/algorithm/for_each.hpp
Normal file
110
boost/range/algorithm/for_each.hpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_FOR_EACH_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
|
||||||
|
#include <xutility>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
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 ::boost::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
|
||||||
|
///
|
||||||
|
/// range-based version of the for_each std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre UnaryFunction is a model of the UnaryFunctionConcept
|
||||||
|
template< class SinglePassRange, class UnaryFunction >
|
||||||
|
inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
|
||||||
|
|
||||||
|
#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
|
||||||
|
template< class SinglePassRange, class UnaryFunction >
|
||||||
|
inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
|
||||||
|
#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
|
||||||
|
using range::for_each;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
49
boost/range/algorithm/generate.hpp
Normal file
49
boost/range/algorithm/generate.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_GENERATE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
/// \brief template function generate
|
||||||
|
///
|
||||||
|
/// range-based version of the generate std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre Generator is a model of the UnaryFunctionConcept
|
||||||
|
template< class ForwardRange, class Generator >
|
||||||
|
inline ForwardRange& generate( ForwardRange& rng, Generator gen )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
std::generate(boost::begin(rng), boost::end(rng), gen);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Generator >
|
||||||
|
inline const ForwardRange& generate( const ForwardRange& rng, Generator gen )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
std::generate(boost::begin(rng), boost::end(rng), gen);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::generate;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
194
boost/range/algorithm/heap_algorithm.hpp
Normal file
194
boost/range/algorithm/heap_algorithm.hpp
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function push_heap
|
||||||
|
///
|
||||||
|
/// range-based version of the push_heap std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre Compare is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& push_heap(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::push_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& push_heap(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::push_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline RandomAccessRange& push_heap(RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function pop_heap
|
||||||
|
///
|
||||||
|
/// range-based version of the pop_heap std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre Compare is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& pop_heap(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::pop_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::pop_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function make_heap
|
||||||
|
///
|
||||||
|
/// range-based version of the make_heap std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre Compare is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& make_heap(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::make_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& make_heap(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::make_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline RandomAccessRange& make_heap(RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function sort_heap
|
||||||
|
///
|
||||||
|
/// range-based version of the sort_heap std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre Compare is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& sort_heap(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::sort_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::sort_heap(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Compare>
|
||||||
|
inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::push_heap;
|
||||||
|
using range::pop_heap;
|
||||||
|
using range::make_heap;
|
||||||
|
using range::sort_heap;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
74
boost/range/algorithm/inplace_merge.hpp
Normal file
74
boost/range/algorithm/inplace_merge.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function inplace_merge
|
||||||
|
///
|
||||||
|
/// range-based version of the inplace_merge std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type middle)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class BinaryPredicate>
|
||||||
|
inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<BidirectionalRange>::type middle,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class BinaryPredicate>
|
||||||
|
inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::inplace_merge;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
58
boost/range/algorithm/lexicographical_compare.hpp
Normal file
58
boost/range/algorithm/lexicographical_compare.hpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function lexicographic_compare
|
||||||
|
///
|
||||||
|
/// range-based version of the lexicographic_compare std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2>
|
||||||
|
inline bool lexicographical_compare(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::lexicographical_compare(
|
||||||
|
boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class BinaryPredicate>
|
||||||
|
inline bool lexicographical_compare(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::lexicographical_compare(
|
||||||
|
boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::lexicographical_compare;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
124
boost/range/algorithm/lower_bound.hpp
Normal file
124
boost/range/algorithm/lower_bound.hpp
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function lower_bound
|
||||||
|
///
|
||||||
|
/// range-based version of the lower_bound std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
>::type
|
||||||
|
lower_bound( ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::lower_bound(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
lower_bound( const ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::lower_bound(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value, class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
>::type
|
||||||
|
lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value, class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
>::type
|
||||||
|
lower_bound( ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
lower_bound( const ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
>::type
|
||||||
|
lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::lower_bound;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
115
boost/range/algorithm/max_element.hpp
Normal file
115
boost/range/algorithm/max_element.hpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function max_element
|
||||||
|
///
|
||||||
|
/// range-based version of the max_element std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
max_element(ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::max_element(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
max_element(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::max_element(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
max_element(ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::max_element(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
max_element(const ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::max_element(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
max_element(ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::pack(
|
||||||
|
std::max_element(boost::begin(rng), boost::end(rng)),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
max_element(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::pack(
|
||||||
|
std::max_element(boost::begin(rng), boost::end(rng)),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
max_element(ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::pack(
|
||||||
|
std::max_element(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
max_element(const ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::pack(
|
||||||
|
std::max_element(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::max_element;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
61
boost/range/algorithm/merge.hpp
Normal file
61
boost/range/algorithm/merge.hpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_MERGE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function merge
|
||||||
|
///
|
||||||
|
/// range-based version of the merge std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
///
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator>
|
||||||
|
inline OutputIterator merge(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::merge(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator, class BinaryPredicate>
|
||||||
|
inline OutputIterator merge(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::merge(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::merge;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
115
boost/range/algorithm/min_element.hpp
Normal file
115
boost/range/algorithm/min_element.hpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function min_element
|
||||||
|
///
|
||||||
|
/// range-based version of the min_element std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
min_element(ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::min_element(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
min_element(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::min_element(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
min_element(ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::min_element(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
min_element(const ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::min_element(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
min_element(ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::pack(
|
||||||
|
std::min_element(boost::begin(rng), boost::end(rng)),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
min_element(const ForwardRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::pack(
|
||||||
|
std::min_element(boost::begin(rng), boost::end(rng)),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
min_element(ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::pack(
|
||||||
|
std::min_element(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class ForwardRange, class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
min_element(const ForwardRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::pack(
|
||||||
|
std::min_element(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::min_element;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
195
boost/range/algorithm/mismatch.hpp
Normal file
195
boost/range/algorithm/mismatch.hpp
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_MISMATCH_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2 >
|
||||||
|
inline std::pair<SinglePassTraversalReadableIterator1,
|
||||||
|
SinglePassTraversalReadableIterator2>
|
||||||
|
mismatch_impl(SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2)
|
||||||
|
{
|
||||||
|
while (first1 != last1 && first2 != last2 && *first1 == *first2)
|
||||||
|
{
|
||||||
|
++first1;
|
||||||
|
++first2;
|
||||||
|
}
|
||||||
|
return std::pair<SinglePassTraversalReadableIterator1,
|
||||||
|
SinglePassTraversalReadableIterator2>(first1, first2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline std::pair<SinglePassTraversalReadableIterator1,
|
||||||
|
SinglePassTraversalReadableIterator2>
|
||||||
|
mismatch_impl(SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
|
||||||
|
{
|
||||||
|
++first1;
|
||||||
|
++first2;
|
||||||
|
}
|
||||||
|
return std::pair<SinglePassTraversalReadableIterator1,
|
||||||
|
SinglePassTraversalReadableIterator2>(first1, first2);
|
||||||
|
}
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
/// \brief template function mismatch
|
||||||
|
///
|
||||||
|
/// range-based version of the mismatch std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||||
|
mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||||
|
mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||||
|
mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||||
|
mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||||
|
mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||||
|
mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||||
|
mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||||
|
inline std::pair<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||||
|
mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::mismatch_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::mismatch;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
74
boost/range/algorithm/nth_element.hpp
Normal file
74
boost/range/algorithm/nth_element.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function nth_element
|
||||||
|
///
|
||||||
|
/// range-based version of the nth_element std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& nth_element(RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::nth_element(boost::begin(rng), nth, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::nth_element(boost::begin(rng), nth, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline RandomAccessRange& nth_element(RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth,
|
||||||
|
BinaryPredicate sort_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth,
|
||||||
|
BinaryPredicate sort_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::nth_element;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
76
boost/range/algorithm/partial_sort.hpp
Normal file
76
boost/range/algorithm/partial_sort.hpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function partial_sort
|
||||||
|
///
|
||||||
|
/// range-based version of the partial_sort std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::partial_sort(boost::begin(rng), middle, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::partial_sort(boost::begin(rng), middle, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle,
|
||||||
|
BinaryPredicate sort_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::partial_sort(boost::begin(rng), middle, boost::end(rng),
|
||||||
|
sort_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle,
|
||||||
|
BinaryPredicate sort_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::partial_sort(boost::begin(rng), middle, boost::end(rng),
|
||||||
|
sort_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::partial_sort;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
82
boost/range/algorithm/partial_sort_copy.hpp
Normal file
82
boost/range/algorithm/partial_sort_copy.hpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function partial_sort_copy
|
||||||
|
///
|
||||||
|
/// range-based version of the partial_sort_copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre RandomAccessRange is a model of the Mutable_RandomAccessRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class SinglePassRange, class RandomAccessRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
|
||||||
|
partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange, class RandomAccessRange>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
|
||||||
|
partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange, class RandomAccessRange,
|
||||||
|
class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
|
||||||
|
partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange, class RandomAccessRange,
|
||||||
|
class BinaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type
|
||||||
|
partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
|
||||||
|
return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::partial_sort_copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
74
boost/range/algorithm/partition.hpp
Normal file
74
boost/range/algorithm/partition.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_PARTITION__HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function partition
|
||||||
|
///
|
||||||
|
/// range-based version of the partition std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template<class ForwardRange, class UnaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
partition(ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::partition(boost::begin(rng),boost::end(rng),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange, class UnaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
partition(const ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::partition(boost::begin(rng),boost::end(rng),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange,
|
||||||
|
class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
partition(ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return boost::range_return<ForwardRange,re>::
|
||||||
|
pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange,
|
||||||
|
class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
partition(const ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return boost::range_return<const ForwardRange,re>::
|
||||||
|
pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::partition;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
108
boost/range/algorithm/permutation.hpp
Normal file
108
boost/range/algorithm/permutation.hpp
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_PERMUTATION_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function next_permutation
|
||||||
|
///
|
||||||
|
/// range-based version of the next_permutation std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
/// \pre Compare is a model of the BinaryPredicateConcept
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline bool next_permutation(BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
return std::next_permutation(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline bool next_permutation(const BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::next_permutation(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class Compare>
|
||||||
|
inline bool next_permutation(BidirectionalRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
return std::next_permutation(boost::begin(rng), boost::end(rng),
|
||||||
|
comp_pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class Compare>
|
||||||
|
inline bool next_permutation(const BidirectionalRange& rng,
|
||||||
|
Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::next_permutation(boost::begin(rng), boost::end(rng),
|
||||||
|
comp_pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function prev_permutation
|
||||||
|
///
|
||||||
|
/// range-based version of the prev_permutation std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
/// \pre Compare is a model of the BinaryPredicateConcept
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline bool prev_permutation(BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
return std::prev_permutation(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline bool prev_permutation(const BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::prev_permutation(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class Compare>
|
||||||
|
inline bool prev_permutation(BidirectionalRange& rng, Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
return std::prev_permutation(boost::begin(rng), boost::end(rng),
|
||||||
|
comp_pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class Compare>
|
||||||
|
inline bool prev_permutation(const BidirectionalRange& rng,
|
||||||
|
Compare comp_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::prev_permutation(boost::begin(rng), boost::end(rng),
|
||||||
|
comp_pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::next_permutation;
|
||||||
|
using range::prev_permutation;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
68
boost/range/algorithm/random_shuffle.hpp
Normal file
68
boost/range/algorithm/random_shuffle.hpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function random_shuffle
|
||||||
|
///
|
||||||
|
/// range-based version of the random_shuffle std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre Generator is a model of the UnaryFunctionConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::random_shuffle(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::random_shuffle(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Generator>
|
||||||
|
inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::random_shuffle(boost::begin(rng), boost::end(rng), gen);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class Generator>
|
||||||
|
inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::random_shuffle(boost::begin(rng), boost::end(rng), gen);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::random_shuffle;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
74
boost/range/algorithm/remove.hpp
Normal file
74
boost/range/algorithm/remove.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REMOVE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function remove
|
||||||
|
///
|
||||||
|
/// range-based version of the remove std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
remove(ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::remove(boost::begin(rng),boost::end(rng),val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
remove(const ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::remove(boost::begin(rng),boost::end(rng),val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
remove(ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::pack(
|
||||||
|
std::remove(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
remove(const ForwardRange& rng, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::pack(
|
||||||
|
std::remove(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::remove;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
44
boost/range/algorithm/remove_copy.hpp
Normal file
44
boost/range/algorithm/remove_copy.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function remove_copy
|
||||||
|
///
|
||||||
|
/// range-based version of the remove_copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre OutputIterator is a model of the OutputIteratorConcept
|
||||||
|
/// \pre Value is a model of the EqualityComparableConcept
|
||||||
|
/// \pre Objects of type Value can be compared for equality with objects of
|
||||||
|
/// InputIterator's value type.
|
||||||
|
template< class SinglePassRange, class OutputIterator, class Value >
|
||||||
|
inline OutputIterator
|
||||||
|
remove_copy(const SinglePassRange& rng, OutputIterator out_it, const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::remove_copy(boost::begin(rng), boost::end(rng), out_it, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::remove_copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
38
boost/range/algorithm/remove_copy_if.hpp
Normal file
38
boost/range/algorithm/remove_copy_if.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
/// \brief template function remove_copy_if
|
||||||
|
///
|
||||||
|
/// range-based version of the remove_copy_if std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre OutputIterator is a model of the OutputIteratorConcept
|
||||||
|
/// \pre Predicate is a model of the PredicateConcept
|
||||||
|
/// \pre InputIterator's value type is convertible to Predicate's argument type
|
||||||
|
/// \pre out_it is not an iterator in the range rng
|
||||||
|
template< class SinglePassRange, class OutputIterator, class Predicate >
|
||||||
|
inline OutputIterator
|
||||||
|
remove_copy_if(const SinglePassRange& rng, OutputIterator out_it, Predicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::remove_copy_if(boost::begin(rng), boost::end(rng), out_it, pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // include guard
|
75
boost/range/algorithm/remove_if.hpp
Normal file
75
boost/range/algorithm/remove_if.hpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REMOVE_IF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function remove_if
|
||||||
|
///
|
||||||
|
/// range-based version of the remove_if std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
|
||||||
|
template< class ForwardRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
|
||||||
|
remove_if(ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::remove_if(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
|
||||||
|
remove_if(const ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::remove_if(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
remove_if(ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::pack(
|
||||||
|
std::remove_if(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class UnaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
remove_if(const ForwardRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::pack(
|
||||||
|
std::remove_if(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::remove_if;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
53
boost/range/algorithm/replace.hpp
Normal file
53
boost/range/algorithm/replace.hpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REPLACE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function replace
|
||||||
|
///
|
||||||
|
/// range-based version of the replace std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline ForwardRange&
|
||||||
|
replace(ForwardRange& rng, const Value& what,
|
||||||
|
const Value& with_what)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
std::replace(boost::begin(rng), boost::end(rng), what, with_what);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline const ForwardRange&
|
||||||
|
replace(const ForwardRange& rng, const Value& what,
|
||||||
|
const Value& with_what)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
std::replace(boost::begin(rng), boost::end(rng), what, with_what);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::replace;
|
||||||
|
} // namespace boost;
|
||||||
|
|
||||||
|
#endif // include guard
|
42
boost/range/algorithm/replace_copy.hpp
Normal file
42
boost/range/algorithm/replace_copy.hpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function replace_copy
|
||||||
|
///
|
||||||
|
/// range-based version of the replace_copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template< class ForwardRange, class OutputIterator, class Value >
|
||||||
|
inline OutputIterator
|
||||||
|
replace_copy(const ForwardRange& rng, OutputIterator out_it, const Value& what,
|
||||||
|
const Value& with_what)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::replace_copy(boost::begin(rng), boost::end(rng), out_it,
|
||||||
|
what, with_what);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::replace_copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
46
boost/range/algorithm/replace_copy_if.hpp
Normal file
46
boost/range/algorithm/replace_copy_if.hpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function replace_copy_if
|
||||||
|
///
|
||||||
|
/// range-based version of the replace_copy_if std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre Predicate is a model of the PredicateConcept
|
||||||
|
/// \pre Value is convertible to Predicate's argument type
|
||||||
|
/// \pre Value is Assignable
|
||||||
|
/// \pre Value is convertible to a type in OutputIterator's set of value types.
|
||||||
|
template< class ForwardRange, class OutputIterator, class Predicate, class Value >
|
||||||
|
inline OutputIterator
|
||||||
|
replace_copy_if(const ForwardRange& rng, OutputIterator out_it, Predicate pred,
|
||||||
|
const Value& with_what)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::replace_copy_if(boost::begin(rng), boost::end(rng), out_it,
|
||||||
|
pred, with_what);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::replace_copy_if;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
54
boost/range/algorithm/replace_if.hpp
Normal file
54
boost/range/algorithm/replace_if.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REPLACE_IF_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function replace_if
|
||||||
|
///
|
||||||
|
/// range-based version of the replace_if std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
|
||||||
|
template< class ForwardRange, class UnaryPredicate, class Value >
|
||||||
|
inline ForwardRange&
|
||||||
|
replace_if(ForwardRange& rng, UnaryPredicate pred,
|
||||||
|
const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class UnaryPredicate, class Value >
|
||||||
|
inline const ForwardRange&
|
||||||
|
replace_if(const ForwardRange& rng, UnaryPredicate pred,
|
||||||
|
const Value& val)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::replace_if;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
50
boost/range/algorithm/reverse.hpp
Normal file
50
boost/range/algorithm/reverse.hpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REVERSE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function reverse
|
||||||
|
///
|
||||||
|
/// range-based version of the reverse std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline BidirectionalRange& reverse(BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
std::reverse(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange>
|
||||||
|
inline const BidirectionalRange& reverse(const BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
std::reverse(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::reverse;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
40
boost/range/algorithm/reverse_copy.hpp
Normal file
40
boost/range/algorithm/reverse_copy.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function reverse_copy
|
||||||
|
///
|
||||||
|
/// range-based version of the reverse_copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
template<class BidirectionalRange, class OutputIterator>
|
||||||
|
inline OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::reverse_copy(boost::begin(rng), boost::end(rng), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::reverse_copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
51
boost/range/algorithm/rotate.hpp
Normal file
51
boost/range/algorithm/rotate.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_ROTATE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function rotate
|
||||||
|
///
|
||||||
|
/// range-based version of the rotate std algorithm
|
||||||
|
///
|
||||||
|
/// \pre Rng meets the requirements for a Forward range
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline ForwardRange& rotate(ForwardRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type middle)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
std::rotate(boost::begin(rng), middle, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class ForwardRange>
|
||||||
|
inline const ForwardRange& rotate(const ForwardRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
std::rotate(boost::begin(rng), middle, boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::rotate;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
44
boost/range/algorithm/rotate_copy.hpp
Normal file
44
boost/range/algorithm/rotate_copy.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function rotate
|
||||||
|
///
|
||||||
|
/// range-based version of the rotate std algorithm
|
||||||
|
///
|
||||||
|
/// \pre Rng meets the requirements for a Forward range
|
||||||
|
template<typename ForwardRange, typename OutputIterator>
|
||||||
|
inline OutputIterator rotate_copy(
|
||||||
|
const ForwardRange& rng,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle,
|
||||||
|
OutputIterator target
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::rotate_copy(boost::begin(rng), middle, boost::end(rng), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::rotate_copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
134
boost/range/algorithm/search.hpp
Normal file
134
boost/range/algorithm/search.hpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_SEARCH_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function search
|
||||||
|
///
|
||||||
|
/// range-based version of the search std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange1 is a model of the ForwardRangeConcept
|
||||||
|
/// \pre ForwardRange2 is a model of the ForwardRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
|
||||||
|
search(ForwardRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return std::search(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
|
||||||
|
search(const ForwardRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return std::search(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
|
||||||
|
search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return std::search(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
|
||||||
|
search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return std::search(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
|
||||||
|
search(ForwardRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return range_return<ForwardRange1,re>::
|
||||||
|
pack(std::search(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2)),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2 >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
|
||||||
|
search(const ForwardRange1& rng1, const ForwardRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return range_return<const ForwardRange1,re>::
|
||||||
|
pack(std::search(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2)),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
|
||||||
|
search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return range_return<ForwardRange1,re>::
|
||||||
|
pack(std::search(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange1, class ForwardRange2,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
|
||||||
|
search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
|
||||||
|
return range_return<const ForwardRange1,re>::
|
||||||
|
pack(std::search(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2),pred),
|
||||||
|
rng1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::search;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
360
boost/range/algorithm/search_n.hpp
Normal file
360
boost/range/algorithm/search_n.hpp
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_SEARCH_N_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
namespace range {
|
||||||
|
|
||||||
|
/// \brief template function search
|
||||||
|
///
|
||||||
|
/// range-based version of the search std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
/// \pre Integer is an integral type
|
||||||
|
/// \pre Value is a model of the EqualityComparableConcept
|
||||||
|
/// \pre ForwardRange's value type is a model of the EqualityComparableConcept
|
||||||
|
/// \pre Object's of ForwardRange's value type can be compared for equality with Objects of type Value
|
||||||
|
template< class ForwardRange, class Integer, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
search_n(ForwardRange& rng, Integer count, const Value& value)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Integer, class Value >
|
||||||
|
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 range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Integer, class Value,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
search_n(ForwardRange& rng, Integer count, const Value& value,
|
||||||
|
BinaryPredicate binary_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
|
||||||
|
return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
|
||||||
|
count, value, binary_pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Integer, class Value,
|
||||||
|
class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
search_n(const ForwardRange& rng, Integer count, const Value& value,
|
||||||
|
BinaryPredicate binary_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
|
||||||
|
return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
|
||||||
|
count, value, binary_pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Integer,
|
||||||
|
class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
search_n(ForwardRange& rng, Integer count, const Value& value)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
|
||||||
|
count, value),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Integer,
|
||||||
|
class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
search_n(const ForwardRange& rng, Integer count, const Value& value)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
|
||||||
|
count, value),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Integer,
|
||||||
|
class Value, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
search_n(ForwardRange& rng, Integer count, const Value& value,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
|
||||||
|
const Value&>));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(range_detail::search_n_pred_impl(boost::begin(rng),
|
||||||
|
boost::end(rng),
|
||||||
|
count, value, pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Integer,
|
||||||
|
class Value, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
search_n(const ForwardRange& rng, Integer count, const Value& value,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
|
||||||
|
const Value&>));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(range_detail::search_n_pred_impl(boost::begin(rng),
|
||||||
|
boost::end(rng),
|
||||||
|
count, value, pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::search_n;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
198
boost/range/algorithm/set_algorithm.hpp
Normal file
198
boost/range/algorithm/set_algorithm.hpp
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function includes
|
||||||
|
///
|
||||||
|
/// range-based version of the includes std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2>
|
||||||
|
inline bool includes(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::includes(boost::begin(rng1),boost::end(rng1),
|
||||||
|
boost::begin(rng2),boost::end(rng2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class BinaryPredicate>
|
||||||
|
inline bool includes(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::includes(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function set_union
|
||||||
|
///
|
||||||
|
/// range-based version of the set_union std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator>
|
||||||
|
inline OutputIterator set_union(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_union(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator, class BinaryPredicate>
|
||||||
|
inline OutputIterator set_union(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_union(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function set_intersection
|
||||||
|
///
|
||||||
|
/// range-based version of the set_intersection std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator>
|
||||||
|
inline OutputIterator set_intersection(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_intersection(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator, class BinaryPredicate>
|
||||||
|
inline OutputIterator set_intersection(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_intersection(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2),
|
||||||
|
out, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function set_difference
|
||||||
|
///
|
||||||
|
/// range-based version of the set_difference std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator>
|
||||||
|
inline OutputIterator set_difference(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_difference(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator, class BinaryPredicate>
|
||||||
|
inline OutputIterator set_difference(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_difference(
|
||||||
|
boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief template function set_symmetric_difference
|
||||||
|
///
|
||||||
|
/// range-based version of the set_symmetric_difference std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator>
|
||||||
|
inline OutputIterator
|
||||||
|
set_symmetric_difference(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2,
|
||||||
|
class OutputIterator, class BinaryPredicate>
|
||||||
|
inline OutputIterator
|
||||||
|
set_symmetric_difference(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return std::set_symmetric_difference(
|
||||||
|
boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2), out, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::includes;
|
||||||
|
using range::set_union;
|
||||||
|
using range::set_intersection;
|
||||||
|
using range::set_difference;
|
||||||
|
using range::set_symmetric_difference;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
68
boost/range/algorithm/sort.hpp
Normal file
68
boost/range/algorithm/sort.hpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_SORT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function sort
|
||||||
|
///
|
||||||
|
/// range-based version of the sort std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& sort(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::sort(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& sort(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::sort(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::sort(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::sort(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::sort;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
73
boost/range/algorithm/stable_partition.hpp
Normal file
73
boost/range/algorithm/stable_partition.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function stable_partition
|
||||||
|
///
|
||||||
|
/// range-based version of the stable_partition std algorithm
|
||||||
|
///
|
||||||
|
/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
|
||||||
|
/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
|
||||||
|
template<class BidirectionalRange, class UnaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type
|
||||||
|
stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
return std::stable_partition(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class BidirectionalRange, class UnaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const BidirectionalRange>::type
|
||||||
|
stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return std::stable_partition(boost::begin(rng),boost::end(rng),pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
// range_return overloads
|
||||||
|
template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<BidirectionalRange,re>::type
|
||||||
|
stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
|
||||||
|
return range_return<BidirectionalRange,re>::pack(
|
||||||
|
std::stable_partition(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const BidirectionalRange,re>::type
|
||||||
|
stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
|
||||||
|
return range_return<const BidirectionalRange,re>::pack(
|
||||||
|
std::stable_partition(boost::begin(rng),boost::end(rng),pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::stable_partition;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
68
boost/range/algorithm/stable_sort.hpp
Normal file
68
boost/range/algorithm/stable_sort.hpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_STABLE_SORT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function stable_sort
|
||||||
|
///
|
||||||
|
/// range-based version of the stable_sort std algorithm
|
||||||
|
///
|
||||||
|
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline RandomAccessRange& stable_sort(RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::stable_sort(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange>
|
||||||
|
inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::stable_sort(boost::begin(rng), boost::end(rng));
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate sort_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
|
||||||
|
std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class RandomAccessRange, class BinaryPredicate>
|
||||||
|
inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate sort_pred)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
|
||||||
|
std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::stable_sort;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
132
boost/range/algorithm/swap_ranges.hpp
Normal file
132
boost/range/algorithm/swap_ranges.hpp
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template<class Iterator1, class Iterator2>
|
||||||
|
void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
|
||||||
|
Iterator2 it2, Iterator2 last2,
|
||||||
|
single_pass_traversal_tag,
|
||||||
|
single_pass_traversal_tag)
|
||||||
|
{
|
||||||
|
ignore_unused_variable_warning(last2);
|
||||||
|
for (; it1 != last1; ++it1, ++it2)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( it2 != last2 );
|
||||||
|
std::iter_swap(it1, it2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator1, class Iterator2>
|
||||||
|
void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
|
||||||
|
Iterator2 it2, Iterator2 last2,
|
||||||
|
random_access_traversal_tag,
|
||||||
|
random_access_traversal_tag)
|
||||||
|
{
|
||||||
|
ignore_unused_variable_warning(last2);
|
||||||
|
BOOST_ASSERT( last2 - it2 >= last1 - it1 );
|
||||||
|
std::swap_ranges(it1, last1, it2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator1, class Iterator2>
|
||||||
|
void swap_ranges_impl(Iterator1 first1, Iterator1 last1,
|
||||||
|
Iterator2 first2, Iterator2 last2)
|
||||||
|
{
|
||||||
|
swap_ranges_impl(first1, last1, first2, last2,
|
||||||
|
BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator1>::type(),
|
||||||
|
BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator2>::type());
|
||||||
|
}
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function swap_ranges
|
||||||
|
///
|
||||||
|
/// range-based version of the swap_ranges std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline SinglePassRange2&
|
||||||
|
swap_ranges(SinglePassRange1& range1, SinglePassRange2& range2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
|
||||||
|
|
||||||
|
boost::range_detail::swap_ranges_impl(
|
||||||
|
boost::begin(range1), boost::end(range1),
|
||||||
|
boost::begin(range2), boost::end(range2));
|
||||||
|
|
||||||
|
return range2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline SinglePassRange2&
|
||||||
|
swap_ranges(const SinglePassRange1& range1, SinglePassRange2& range2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
|
||||||
|
|
||||||
|
boost::range_detail::swap_ranges_impl(
|
||||||
|
boost::begin(range1), boost::end(range1),
|
||||||
|
boost::begin(range2), boost::end(range2));
|
||||||
|
|
||||||
|
return range2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline const SinglePassRange2&
|
||||||
|
swap_ranges(SinglePassRange1& range1, const SinglePassRange2& range2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
|
||||||
|
|
||||||
|
boost::range_detail::swap_ranges_impl(
|
||||||
|
boost::begin(range1), boost::end(range1),
|
||||||
|
boost::begin(range2), boost::end(range2));
|
||||||
|
|
||||||
|
return range2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline const SinglePassRange2&
|
||||||
|
swap_ranges(const SinglePassRange1& range1, const SinglePassRange2& range2)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
|
||||||
|
|
||||||
|
boost::range_detail::swap_ranges_impl(
|
||||||
|
boost::begin(range1), boost::end(range1),
|
||||||
|
boost::begin(range2), boost::end(range2));
|
||||||
|
|
||||||
|
return range2;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::swap_ranges;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
96
boost/range/algorithm/transform.hpp
Normal file
96
boost/range/algorithm/transform.hpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_TRANSFORM_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function transform
|
||||||
|
///
|
||||||
|
/// range-based version of the transform std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre OutputIterator is a model of the OutputIteratorConcept
|
||||||
|
/// \pre UnaryOperation is a model of the UnaryFunctionConcept
|
||||||
|
/// \pre BinaryOperation is a model of the BinaryFunctionConcept
|
||||||
|
template< class SinglePassRange1,
|
||||||
|
class OutputIterator,
|
||||||
|
class UnaryOperation >
|
||||||
|
inline OutputIterator
|
||||||
|
transform(const SinglePassRange1& rng,
|
||||||
|
OutputIterator out,
|
||||||
|
UnaryOperation fun)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
return std::transform(boost::begin(rng),boost::end(rng),out,fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class SinglePassTraversalReadableIterator1,
|
||||||
|
class SinglePassTraversalReadableIterator2,
|
||||||
|
class OutputIterator,
|
||||||
|
class BinaryFunction >
|
||||||
|
inline OutputIterator
|
||||||
|
transform_impl(SinglePassTraversalReadableIterator1 first1,
|
||||||
|
SinglePassTraversalReadableIterator1 last1,
|
||||||
|
SinglePassTraversalReadableIterator2 first2,
|
||||||
|
SinglePassTraversalReadableIterator2 last2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryFunction fn)
|
||||||
|
{
|
||||||
|
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||||
|
{
|
||||||
|
*out = fn(*first1, *first2);
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange1,
|
||||||
|
class SinglePassRange2,
|
||||||
|
class OutputIterator,
|
||||||
|
class BinaryOperation >
|
||||||
|
inline OutputIterator
|
||||||
|
transform(const SinglePassRange1& rng1,
|
||||||
|
const SinglePassRange2& rng2,
|
||||||
|
OutputIterator out,
|
||||||
|
BinaryOperation fun)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
return boost::range_detail::transform_impl(
|
||||||
|
boost::begin(rng1), boost::end(rng1),
|
||||||
|
boost::begin(rng2), boost::end(rng2),
|
||||||
|
out, fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::transform;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
107
boost/range/algorithm/unique.hpp
Normal file
107
boost/range/algorithm/unique.hpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_UNIQUE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function unique
|
||||||
|
///
|
||||||
|
/// range-based version of the unique std algorithm
|
||||||
|
///
|
||||||
|
/// \pre Rng meets the requirements for a Forward range
|
||||||
|
template< range_return_value re, class ForwardRange >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
unique( ForwardRange& rng )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack( std::unique( boost::begin(rng),
|
||||||
|
boost::end(rng)), rng );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
unique( const ForwardRange& rng )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack( std::unique( boost::begin(rng),
|
||||||
|
boost::end(rng)), rng );
|
||||||
|
}
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
unique( ForwardRange& rng, BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::unique(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
unique( const ForwardRange& rng, BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::unique(boost::begin(rng), boost::end(rng), pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
|
||||||
|
unique( ForwardRange& rng )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return ::boost::range::unique<return_begin_found>(rng);
|
||||||
|
}
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
|
||||||
|
unique( const ForwardRange& rng )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return ::boost::range::unique<return_begin_found>(rng);
|
||||||
|
}
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
|
||||||
|
unique( ForwardRange& rng, BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return ::boost::range::unique<return_begin_found>(rng, pred);
|
||||||
|
}
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class BinaryPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
|
||||||
|
unique( const ForwardRange& rng, BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return ::boost::range::unique<return_begin_found>(rng, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::unique;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
51
boost/range/algorithm/unique_copy.hpp
Normal file
51
boost/range/algorithm/unique_copy.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function unique_copy
|
||||||
|
///
|
||||||
|
/// range-based version of the unique_copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre OutputIterator is a model of the OutputIteratorConcept
|
||||||
|
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||||
|
template< class SinglePassRange, class OutputIterator >
|
||||||
|
inline OutputIterator
|
||||||
|
unique_copy( const SinglePassRange& rng, OutputIterator out_it )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::unique_copy(boost::begin(rng), boost::end(rng), out_it);
|
||||||
|
}
|
||||||
|
/// \overload
|
||||||
|
template< class SinglePassRange, class OutputIterator, class BinaryPredicate >
|
||||||
|
inline OutputIterator
|
||||||
|
unique_copy( const SinglePassRange& rng, OutputIterator out_it,
|
||||||
|
BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
return std::unique_copy(boost::begin(rng), boost::end(rng), out_it, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::unique_copy;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
127
boost/range/algorithm/upper_bound.hpp
Normal file
127
boost/range/algorithm/upper_bound.hpp
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function upper_bound
|
||||||
|
///
|
||||||
|
/// range-based version of the upper_bound std algorithm
|
||||||
|
///
|
||||||
|
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline
|
||||||
|
BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
>::type
|
||||||
|
upper_bound( ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::upper_bound(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
upper_bound( const ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::upper_bound(boost::begin(rng), boost::end(rng), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value, class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||||
|
>::type
|
||||||
|
upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< class ForwardRange, class Value, class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||||
|
upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
>::type
|
||||||
|
upper_bound( ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
upper_bound( const ForwardRange& rng, Value val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value,
|
||||||
|
class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME disable_if<
|
||||||
|
is_const<ForwardRange>,
|
||||||
|
BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||||
|
>::type
|
||||||
|
upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
return range_return<ForwardRange,re>::
|
||||||
|
pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template< range_return_value re, class ForwardRange, class Value,
|
||||||
|
class SortPredicate >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||||
|
upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
return range_return<const ForwardRange,re>::
|
||||||
|
pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
|
||||||
|
rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::upper_bound;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
28
boost/range/algorithm_ext.hpp
Normal file
28
boost/range/algorithm_ext.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2007. 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 Thorsten Ottosen 2006. 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_ALGORITHM_EXT_HPP
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_HPP
|
||||||
|
|
||||||
|
#include <boost/range/algorithm_ext/copy_n.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/for_each.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/is_sorted.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/iota.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/overwrite.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/push_back.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/push_front.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/insert.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/erase.hpp>
|
||||||
|
|
||||||
|
#endif
|
53
boost/range/algorithm_ext/copy_n.hpp
Normal file
53
boost/range/algorithm_ext/copy_n.hpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_COPY_N_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/distance.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function copy
|
||||||
|
///
|
||||||
|
/// range-based version of the copy std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
/// \pre OutputIterator is a model of the OutputIteratorConcept
|
||||||
|
/// \pre 0 <= n <= distance(rng)
|
||||||
|
template< class SinglePassRange, class Size, class OutputIterator >
|
||||||
|
inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
|
||||||
|
BOOST_ASSERT( n <= static_cast<Size>(::boost::distance(rng)) );
|
||||||
|
BOOST_ASSERT( n >= static_cast<Size>(0) );
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type source = ::boost::begin(rng);
|
||||||
|
|
||||||
|
for (Size i = 0; i < n; ++i, ++out, ++source)
|
||||||
|
*out = *source;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using ::boost::range::copy_n;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
61
boost/range/algorithm_ext/erase.hpp
Normal file
61
boost/range/algorithm_ext/erase.hpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_ERASE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class Container >
|
||||||
|
inline Container& erase( Container& on,
|
||||||
|
iterator_range<BOOST_DEDUCED_TYPENAME Container::iterator> to_erase )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
|
||||||
|
on.erase( boost::begin(to_erase), boost::end(to_erase) );
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class T >
|
||||||
|
inline Container& remove_erase( Container& on, const T& val )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
|
||||||
|
on.erase(
|
||||||
|
std::remove(boost::begin(on), boost::end(on), val),
|
||||||
|
boost::end(on));
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Pred >
|
||||||
|
inline Container& remove_erase_if( Container& on, Pred pred )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
|
||||||
|
on.erase(
|
||||||
|
std::remove_if(boost::begin(on), boost::end(on), pred),
|
||||||
|
boost::end(on));
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::erase;
|
||||||
|
using range::remove_erase;
|
||||||
|
using range::remove_erase_if;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
86
boost/range/algorithm_ext/for_each.hpp
Normal file
86
boost/range/algorithm_ext/for_each.hpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template<class InputIterator1, class InputIterator2, class Fn2>
|
||||||
|
inline Fn2 for_each_impl(InputIterator1 first1, InputIterator1 last1,
|
||||||
|
InputIterator2 first2, InputIterator2 last2,
|
||||||
|
Fn2 fn)
|
||||||
|
{
|
||||||
|
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||||
|
{
|
||||||
|
fn(*first1, *first2);
|
||||||
|
}
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2, class Fn2>
|
||||||
|
inline Fn2 for_each(const SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::for_each_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2, class Fn2>
|
||||||
|
inline Fn2 for_each(const SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::for_each_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2, class Fn2>
|
||||||
|
inline Fn2 for_each(SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::for_each_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange1, class SinglePassRange2, class Fn2>
|
||||||
|
inline Fn2 for_each(SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
return ::boost::range_detail::for_each_impl(
|
||||||
|
::boost::begin(rng1), ::boost::end(rng1),
|
||||||
|
::boost::begin(rng2), ::boost::end(rng2), fn);
|
||||||
|
}
|
||||||
|
} // namespace range
|
||||||
|
using range::for_each;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
48
boost/range/algorithm_ext/insert.hpp
Normal file
48
boost/range/algorithm_ext/insert.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_INSERT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class Container, class Range >
|
||||||
|
inline Container& insert( Container& on,
|
||||||
|
BOOST_DEDUCED_TYPENAME Container::iterator before,
|
||||||
|
const Range& from )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
|
||||||
|
on.insert( before, boost::begin(from), boost::end(from) );
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Range >
|
||||||
|
inline Container& insert( Container& on, const Range& from )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
|
||||||
|
on.insert(boost::begin(from), boost::end(from));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::insert;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
54
boost/range/algorithm_ext/iota.hpp
Normal file
54
boost/range/algorithm_ext/iota.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_IOTA_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline ForwardRange& iota( ForwardRange& rng, Value x )
|
||||||
|
{
|
||||||
|
BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
|
||||||
|
|
||||||
|
iterator_t last_target = ::boost::end(rng);
|
||||||
|
for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
|
||||||
|
*target = x;
|
||||||
|
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class ForwardRange, class Value >
|
||||||
|
inline const ForwardRange& iota( const ForwardRange& rng, Value x )
|
||||||
|
{
|
||||||
|
BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type iterator_t;
|
||||||
|
|
||||||
|
iterator_t last_target = ::boost::end(rng);
|
||||||
|
for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
|
||||||
|
*target = x;
|
||||||
|
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::iota;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
57
boost/range/algorithm_ext/is_sorted.hpp
Normal file
57
boost/range/algorithm_ext/is_sorted.hpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright Bryce Lelbach 2010
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/detail/is_sorted.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \brief template function is_sorted
|
||||||
|
///
|
||||||
|
/// range-based version of the is_sorted std algorithm
|
||||||
|
///
|
||||||
|
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
|
||||||
|
template<class SinglePassRange>
|
||||||
|
inline bool is_sorted(const SinglePassRange& rng)
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept<BOOST_DEDUCED_TYPENAME
|
||||||
|
range_value<const SinglePassRange>::type>));
|
||||||
|
return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \overload
|
||||||
|
template<class SinglePassRange, class BinaryPredicate>
|
||||||
|
inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred)
|
||||||
|
{
|
||||||
|
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>));
|
||||||
|
return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
|
||||||
|
using range::is_sorted;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
84
boost/range/algorithm_ext/overwrite.hpp
Normal file
84
boost/range/algorithm_ext/overwrite.hpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline void overwrite( const SinglePassRange1& from, SinglePassRange2& to )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
|
||||||
|
i = boost::begin(from), e = boost::end(from);
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
|
||||||
|
out = boost::begin(to);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
|
||||||
|
last_out = boost::end(to);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( ; i != e; ++out, ++i )
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
BOOST_ASSERT( out != last_out
|
||||||
|
&& "out of bounds in boost::overwrite()" );
|
||||||
|
#endif
|
||||||
|
*out = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class SinglePassRange1, class SinglePassRange2 >
|
||||||
|
inline void overwrite( const SinglePassRange1& from, const SinglePassRange2& to )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
|
||||||
|
i = boost::begin(from), e = boost::end(from);
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
|
||||||
|
out = boost::begin(to);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
|
||||||
|
last_out = boost::end(to);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( ; i != e; ++out, ++i )
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
BOOST_ASSERT( out != last_out
|
||||||
|
&& "out of bounds in boost::overwrite()" );
|
||||||
|
#endif
|
||||||
|
*out = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::overwrite;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
41
boost/range/algorithm_ext/push_back.hpp
Normal file
41
boost/range/algorithm_ext/push_back.hpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/detail/implementation_help.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class Container, class Range >
|
||||||
|
inline Container& push_back( Container& on, const Range& from )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
|
||||||
|
BOOST_ASSERT_MSG(!range_detail::is_same_object(on, from),
|
||||||
|
"cannot copy from a container to itself");
|
||||||
|
on.insert( on.end(), boost::begin(from), boost::end(from) );
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::push_back;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
41
boost/range/algorithm_ext/push_front.hpp
Normal file
41
boost/range/algorithm_ext/push_front.hpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. 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_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/detail/implementation_help.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class Container, class Range >
|
||||||
|
inline Container& push_front( Container& on, const Range& from )
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
|
||||||
|
BOOST_ASSERT_MSG(!range_detail::is_same_object(on, from),
|
||||||
|
"cannot copy from a container to itself");
|
||||||
|
on.insert( on.begin(), boost::begin(from), boost::end(from) );
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
using range::push_front;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
204
boost/range/any_range.hpp
Normal file
204
boost/range/any_range.hpp
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
// 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_ANY_RANGE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/range/detail/any_iterator.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/reference.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
// If T is use_default, return the result of Default, otherwise
|
||||||
|
// return T.
|
||||||
|
//
|
||||||
|
// This is an implementation artifact used to pick intelligent default
|
||||||
|
// values when the user specified boost::use_default as a template
|
||||||
|
// parameter.
|
||||||
|
template<
|
||||||
|
class T,
|
||||||
|
class Default
|
||||||
|
>
|
||||||
|
struct any_range_default_help
|
||||||
|
: mpl::eval_if<
|
||||||
|
is_same<T, use_default>
|
||||||
|
, Default
|
||||||
|
, mpl::identity<T>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedRange
|
||||||
|
, class Value
|
||||||
|
, class Reference
|
||||||
|
>
|
||||||
|
struct any_range_value_type
|
||||||
|
{
|
||||||
|
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||||
|
typedef typename any_range_default_help<
|
||||||
|
Value
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_same<Reference, use_default>
|
||||||
|
, range_value<
|
||||||
|
typename remove_const<WrappedRange>
|
||||||
|
::type>
|
||||||
|
, remove_reference<Reference>
|
||||||
|
>
|
||||||
|
>::type type;
|
||||||
|
# else
|
||||||
|
typedef typename any_range_default_help<
|
||||||
|
Value
|
||||||
|
, range_value<
|
||||||
|
typename remove_const<WrappedRange>
|
||||||
|
::type>
|
||||||
|
>::type type;
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference = Value&
|
||||||
|
, class Difference = std::ptrdiff_t
|
||||||
|
, class Buffer = use_default
|
||||||
|
>
|
||||||
|
class any_range
|
||||||
|
: public iterator_range<
|
||||||
|
any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Buffer
|
||||||
|
, mpl::identity<any_iterator_default_buffer>
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef iterator_range<
|
||||||
|
any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Buffer
|
||||||
|
, mpl::identity<any_iterator_default_buffer>
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
struct enabler {};
|
||||||
|
struct disabler {};
|
||||||
|
public:
|
||||||
|
any_range()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
any_range(const any_range& other)
|
||||||
|
: base_type(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class WrappedRange>
|
||||||
|
any_range(WrappedRange& wrapped_range)
|
||||||
|
: base_type(boost::begin(wrapped_range),
|
||||||
|
boost::end(wrapped_range))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class WrappedRange>
|
||||||
|
any_range(const WrappedRange& wrapped_range)
|
||||||
|
: base_type(boost::begin(wrapped_range),
|
||||||
|
boost::end(wrapped_range))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
class OtherValue
|
||||||
|
, class OtherTraversal
|
||||||
|
, class OtherReference
|
||||||
|
, class OtherDifference
|
||||||
|
>
|
||||||
|
any_range(const any_range<
|
||||||
|
OtherValue
|
||||||
|
, OtherTraversal
|
||||||
|
, OtherReference
|
||||||
|
, OtherDifference
|
||||||
|
, Buffer
|
||||||
|
>& other)
|
||||||
|
: base_type(boost::begin(other), boost::end(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
any_range(Iterator first, Iterator last)
|
||||||
|
: base_type(first, last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedRange
|
||||||
|
, class Value = use_default
|
||||||
|
, class Traversal = use_default
|
||||||
|
, class Reference = use_default
|
||||||
|
, class Difference = use_default
|
||||||
|
, class Buffer = use_default
|
||||||
|
>
|
||||||
|
struct any_range_type_generator
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<WrappedRange> ));
|
||||||
|
typedef any_range<
|
||||||
|
typename any_range_value_type<
|
||||||
|
WrappedRange
|
||||||
|
, Value
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Reference
|
||||||
|
, range_reference<WrappedRange>
|
||||||
|
>::type
|
||||||
|
>::type
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Traversal
|
||||||
|
, iterator_traversal<
|
||||||
|
typename range_iterator<WrappedRange>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Reference
|
||||||
|
, range_reference<WrappedRange>
|
||||||
|
>::type
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Difference
|
||||||
|
, range_difference<WrappedRange>
|
||||||
|
>::type
|
||||||
|
, typename any_range_default_help<
|
||||||
|
Buffer
|
||||||
|
, mpl::identity<any_iterator_default_buffer>
|
||||||
|
>::type
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
using range_detail::any_range;
|
||||||
|
using range_detail::any_range_type_generator;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
45
boost/range/as_array.hpp
Normal file
45
boost/range/as_array.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2006. 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_AS_ARRAY_HPP
|
||||||
|
#define BOOST_RANGE_AS_ARRAY_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/detail/str_types.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class R >
|
||||||
|
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<R>::type >
|
||||||
|
as_array( R& r )
|
||||||
|
{
|
||||||
|
return boost::make_iterator_range( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
|
||||||
|
template< class Range >
|
||||||
|
inline boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
|
||||||
|
as_array( const Range& r )
|
||||||
|
{
|
||||||
|
return boost::make_iterator_range( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
127
boost/range/as_literal.hpp
Normal file
127
boost/range/as_literal.hpp
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2006. 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_AS_LITERAL_HPP
|
||||||
|
#define BOOST_RANGE_AS_LITERAL_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
#include <boost/range/detail/as_literal.hpp>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <boost/range/detail/str_types.hpp>
|
||||||
|
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#ifndef BOOST_NO_CWCHAR
|
||||||
|
#include <cwchar>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
inline std::size_t length( const char* s )
|
||||||
|
{
|
||||||
|
return strlen( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CWCHAR
|
||||||
|
inline std::size_t length( const wchar_t* s )
|
||||||
|
{
|
||||||
|
return wcslen( s );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remark: the compiler cannot choose between T* and T[sz]
|
||||||
|
// overloads, so we must put the T* internal to the
|
||||||
|
// unconstrained version.
|
||||||
|
//
|
||||||
|
|
||||||
|
inline bool is_char_ptr( char* )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_char_ptr( const char* )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CWCHAR
|
||||||
|
inline bool is_char_ptr( wchar_t* )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_char_ptr( const wchar_t* )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline long is_char_ptr( const T& /* r */ )
|
||||||
|
{
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline iterator_range<T*>
|
||||||
|
make_range( T* const r, bool )
|
||||||
|
{
|
||||||
|
return iterator_range<T*>( r, r + length(r) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<T>::type>
|
||||||
|
make_range( T& r, long )
|
||||||
|
{
|
||||||
|
return boost::make_iterator_range( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Range >
|
||||||
|
inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type>
|
||||||
|
as_literal( Range& r )
|
||||||
|
{
|
||||||
|
return range_detail::make_range( r, range_detail::is_char_ptr(r) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Range >
|
||||||
|
inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type>
|
||||||
|
as_literal( const Range& r )
|
||||||
|
{
|
||||||
|
return range_detail::make_range( r, range_detail::is_char_ptr(r) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Char, std::size_t sz >
|
||||||
|
inline iterator_range<Char*> as_literal( Char (&arr)[sz] )
|
||||||
|
{
|
||||||
|
return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Char, std::size_t sz >
|
||||||
|
inline iterator_range<const Char*> as_literal( const Char (&arr)[sz] )
|
||||||
|
{
|
||||||
|
return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
|
||||||
|
#endif
|
724
boost/range/atl.hpp
Normal file
724
boost/range/atl.hpp
Normal file
|
@ -0,0 +1,724 @@
|
||||||
|
#ifndef BOOST_RANGE_ATL_HPP
|
||||||
|
#define BOOST_RANGE_ATL_HPP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Boost.Range ATL Extension
|
||||||
|
//
|
||||||
|
// Copyright Shunsuke Sogame 2005-2006.
|
||||||
|
// Distributed under 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// config
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <atldef.h> // _ATL_VER
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
#if (_ATL_VER < 0x0700)
|
||||||
|
#define BOOST_RANGE_ATL_NO_COLLECTIONS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
#if (_ATL_VER < 0x0700) // dubious
|
||||||
|
#define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <basetyps.h> // IID
|
||||||
|
|
||||||
|
|
||||||
|
namespace ATL {
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
// arrays
|
||||||
|
//
|
||||||
|
template< class E, class ETraits >
|
||||||
|
class CAtlArray;
|
||||||
|
|
||||||
|
template< class E >
|
||||||
|
class CAutoPtrArray;
|
||||||
|
|
||||||
|
template< class I, const IID *piid >
|
||||||
|
class CInterfaceArray;
|
||||||
|
|
||||||
|
|
||||||
|
// lists
|
||||||
|
//
|
||||||
|
template< class E, class ETraits >
|
||||||
|
class CAtlList;
|
||||||
|
|
||||||
|
template< class E >
|
||||||
|
class CAutoPtrList;
|
||||||
|
|
||||||
|
template< class E, class Allocator >
|
||||||
|
class CHeapPtrList;
|
||||||
|
|
||||||
|
template< class I, const IID *piid >
|
||||||
|
class CInterfaceList;
|
||||||
|
|
||||||
|
|
||||||
|
// maps
|
||||||
|
//
|
||||||
|
template< class K, class V, class KTraits, class VTraits >
|
||||||
|
class CAtlMap;
|
||||||
|
|
||||||
|
template< class K, class V, class KTraits, class VTraits >
|
||||||
|
class CRBTree;
|
||||||
|
|
||||||
|
template< class K, class V, class KTraits, class VTraits >
|
||||||
|
class CRBMap;
|
||||||
|
|
||||||
|
template< class K, class V, class KTraits, class VTraits >
|
||||||
|
class CRBMultiMap;
|
||||||
|
|
||||||
|
|
||||||
|
// strings
|
||||||
|
//
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
|
||||||
|
template< class BaseType, bool t_bMFCDLL >
|
||||||
|
class CSimpleStringT;
|
||||||
|
#else
|
||||||
|
template< class BaseType >
|
||||||
|
class CSimpleStringT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template< class BaseType, class StringTraits >
|
||||||
|
class CStringT;
|
||||||
|
|
||||||
|
template< class StringType, int t_nChars >
|
||||||
|
class CFixedStringT;
|
||||||
|
|
||||||
|
template< class BaseType, const int t_nSize >
|
||||||
|
class CStaticString;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
// simples
|
||||||
|
//
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
|
||||||
|
template< class T, class TEqual >
|
||||||
|
class CSimpleArray;
|
||||||
|
|
||||||
|
template< class TKey, class TVal, class TEqual >
|
||||||
|
class CSimpleMap;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
class CSimpleArray;
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
class CSimpleValArray;
|
||||||
|
|
||||||
|
template< class TKey, class TVal >
|
||||||
|
class CSimpleMap;
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
|
||||||
|
|
||||||
|
// pointers
|
||||||
|
//
|
||||||
|
template< class E >
|
||||||
|
class CAutoPtr;
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
class CComPtr;
|
||||||
|
|
||||||
|
template< class T, const IID *piid >
|
||||||
|
class CComQIPtr;
|
||||||
|
|
||||||
|
template< class E, class Allocator >
|
||||||
|
class CHeapPtr;
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
class CAdapt;
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ATL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// indirect_iterator customizations
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <boost/mpl/identity.hpp>
|
||||||
|
#include <boost/pointee.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
|
||||||
|
template< class E >
|
||||||
|
struct pointee< ATL::CAutoPtr<E> > :
|
||||||
|
mpl::identity<E>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct pointee< ATL::CComPtr<T> > :
|
||||||
|
mpl::identity<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class T, const IID *piid >
|
||||||
|
struct pointee< ATL::CComQIPtr<T, piid> > :
|
||||||
|
mpl::identity<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class E, class Allocator >
|
||||||
|
struct pointee< ATL::CHeapPtr<E, Allocator> > :
|
||||||
|
mpl::identity<E>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct pointee< ATL::CAdapt<T> > :
|
||||||
|
pointee<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// extended customizations
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <boost/iterator/indirect_iterator.hpp>
|
||||||
|
#include <boost/iterator/zip_iterator.hpp>
|
||||||
|
#include <boost/range/detail/microsoft.hpp>
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <atlbase.h> // CComBSTR
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost { namespace range_detail_microsoft {
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
// arrays
|
||||||
|
//
|
||||||
|
|
||||||
|
struct atl_array_functions :
|
||||||
|
array_functions
|
||||||
|
{
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator end(X& x) // redefine
|
||||||
|
{
|
||||||
|
return x.GetData() + x.GetCount(); // no 'GetSize()'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class E, class ETraits >
|
||||||
|
struct customization< ATL::CAtlArray<E, ETraits> > :
|
||||||
|
atl_array_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef E val_t;
|
||||||
|
|
||||||
|
typedef val_t *mutable_iterator;
|
||||||
|
typedef val_t const *const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class E >
|
||||||
|
struct customization< ATL::CAutoPtrArray<E> > :
|
||||||
|
atl_array_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
// ATL::CAutoPtr/CHeapPtr is no assignable.
|
||||||
|
typedef ATL::CAutoPtr<E> val_t;
|
||||||
|
typedef val_t *miter_t;
|
||||||
|
typedef val_t const *citer_t;
|
||||||
|
|
||||||
|
typedef indirect_iterator<miter_t> mutable_iterator;
|
||||||
|
typedef indirect_iterator<citer_t> const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class I, const IID *piid >
|
||||||
|
struct customization< ATL::CInterfaceArray<I, piid> > :
|
||||||
|
atl_array_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef ATL::CComQIPtr<I, piid> val_t;
|
||||||
|
|
||||||
|
typedef val_t *mutable_iterator;
|
||||||
|
typedef val_t const *const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class E, class ETraits >
|
||||||
|
struct customization< ATL::CAtlList<E, ETraits> > :
|
||||||
|
list_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef E val_t;
|
||||||
|
|
||||||
|
typedef list_iterator<X, val_t> mutable_iterator;
|
||||||
|
typedef list_iterator<X const, val_t const> const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct indirected_list_functions
|
||||||
|
{
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator begin(X& x)
|
||||||
|
{
|
||||||
|
typedef typename Iterator::base_type base_t; // == list_iterator
|
||||||
|
return Iterator(base_t(x, x.GetHeadPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator end(X& x)
|
||||||
|
{
|
||||||
|
typedef typename Iterator::base_type base_t;
|
||||||
|
return Iterator(base_t(x, POSITION(0)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class E >
|
||||||
|
struct customization< ATL::CAutoPtrList<E> > :
|
||||||
|
indirected_list_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef ATL::CAutoPtr<E> val_t;
|
||||||
|
typedef list_iterator<X, val_t> miter_t;
|
||||||
|
typedef list_iterator<X const, val_t const> citer_t;
|
||||||
|
|
||||||
|
typedef indirect_iterator<miter_t> mutable_iterator;
|
||||||
|
typedef indirect_iterator<citer_t> const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class E, class Allocator >
|
||||||
|
struct customization< ATL::CHeapPtrList<E, Allocator> > :
|
||||||
|
indirected_list_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef ATL::CHeapPtr<E, Allocator> val_t;
|
||||||
|
typedef list_iterator<X, val_t> miter_t;
|
||||||
|
typedef list_iterator<X const, val_t const> citer_t;
|
||||||
|
|
||||||
|
typedef indirect_iterator<miter_t> mutable_iterator;
|
||||||
|
typedef indirect_iterator<citer_t> const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class I, const IID *piid >
|
||||||
|
struct customization< ATL::CInterfaceList<I, piid> > :
|
||||||
|
list_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef ATL::CComQIPtr<I, piid> val_t;
|
||||||
|
|
||||||
|
typedef list_iterator<X, val_t> mutable_iterator;
|
||||||
|
typedef list_iterator<X const, val_t const> const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// maps
|
||||||
|
//
|
||||||
|
|
||||||
|
struct atl_rb_tree_tag
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< >
|
||||||
|
struct customization< atl_rb_tree_tag > :
|
||||||
|
indirected_list_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef typename X::CPair val_t;
|
||||||
|
|
||||||
|
typedef list_iterator<X, val_t *, val_t *> miter_t;
|
||||||
|
typedef list_iterator<X const, val_t const *, val_t const *> citer_t;
|
||||||
|
|
||||||
|
typedef indirect_iterator<miter_t> mutable_iterator;
|
||||||
|
typedef indirect_iterator<citer_t> const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class K, class V, class KTraits, class VTraits >
|
||||||
|
struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > :
|
||||||
|
customization< atl_rb_tree_tag >
|
||||||
|
{
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator begin(X& x) // redefine
|
||||||
|
{
|
||||||
|
typedef typename Iterator::base_type base_t; // == list_iterator
|
||||||
|
return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// strings
|
||||||
|
//
|
||||||
|
|
||||||
|
struct atl_string_tag
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< >
|
||||||
|
struct customization< atl_string_tag >
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef typename X::PXSTR mutable_iterator;
|
||||||
|
typedef typename X::PCXSTR const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
typename mutable_<Iterator, X>::type begin(X& x)
|
||||||
|
{
|
||||||
|
return x.GetBuffer(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator begin(X const& x)
|
||||||
|
{
|
||||||
|
return x.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator end(X& x)
|
||||||
|
{
|
||||||
|
return begin<Iterator>(x) + x.GetLength();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template< class BaseType, const int t_nSize >
|
||||||
|
struct customization< ATL::CStaticString<BaseType, t_nSize> >
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef BaseType const *mutable_iterator;
|
||||||
|
typedef mutable_iterator const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator begin(X const& x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator end(X const& x)
|
||||||
|
{
|
||||||
|
return begin<Iterator>(x) + X::GetLength();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
template< >
|
||||||
|
struct customization< ATL::CComBSTR >
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef OLECHAR *mutable_iterator;
|
||||||
|
typedef OLECHAR const *const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator begin(X& x)
|
||||||
|
{
|
||||||
|
return x.operator BSTR();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator end(X& x)
|
||||||
|
{
|
||||||
|
return begin<Iterator>(x) + x.Length();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// simples
|
||||||
|
//
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
template< class T, class TEqual >
|
||||||
|
struct customization< ATL::CSimpleArray<T, TEqual> > :
|
||||||
|
#else
|
||||||
|
template< class T >
|
||||||
|
struct customization< ATL::CSimpleArray<T> > :
|
||||||
|
#endif
|
||||||
|
array_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef T val_t;
|
||||||
|
|
||||||
|
typedef val_t *mutable_iterator;
|
||||||
|
typedef val_t const *const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct customization< ATL::CSimpleValArray<T> > :
|
||||||
|
array_functions
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef T val_t;
|
||||||
|
|
||||||
|
typedef val_t *mutable_iterator;
|
||||||
|
typedef val_t const *const_iterator;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
template< class TKey, class TVal, class TEqual >
|
||||||
|
struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> >
|
||||||
|
#else
|
||||||
|
template< class TKey, class TVal >
|
||||||
|
struct customization< ATL::CSimpleMap<TKey, TVal> >
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
template< class X >
|
||||||
|
struct meta
|
||||||
|
{
|
||||||
|
typedef TKey k_val_t;
|
||||||
|
typedef k_val_t *k_miter_t;
|
||||||
|
typedef k_val_t const *k_citer_t;
|
||||||
|
|
||||||
|
typedef TVal v_val_t;
|
||||||
|
typedef v_val_t *v_miter_t;
|
||||||
|
typedef v_val_t const *v_citer_t;
|
||||||
|
|
||||||
|
// Topic:
|
||||||
|
// 'std::pair' can't contain references
|
||||||
|
// because of reference to reference problem.
|
||||||
|
|
||||||
|
typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator;
|
||||||
|
typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator begin(X& x)
|
||||||
|
{
|
||||||
|
return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal));
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Iterator, class X >
|
||||||
|
Iterator end(X& x)
|
||||||
|
{
|
||||||
|
return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} } // namespace boost::range_detail_microsoft
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// range customizations
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
// arrays
|
||||||
|
//
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CAtlArray, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CAutoPtrArray, 1
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// lists
|
||||||
|
//
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CAtlList, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CAutoPtrList, 1
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CHeapPtrList, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
//maps
|
||||||
|
//
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CAtlMap, 4
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_rb_tree_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CRBTree, 4
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_rb_tree_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CRBMap, 4
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_rb_tree_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CRBMultiMap, 4
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// strings
|
||||||
|
//
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_string_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool)
|
||||||
|
)
|
||||||
|
#else
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_string_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleStringT, 1
|
||||||
|
)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_string_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CStringT, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::atl_string_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CFixedStringT, (class)(int)
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CStaticString, (class)(const int)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CComBSTR
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// simples
|
||||||
|
//
|
||||||
|
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleArray, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleMap, 3
|
||||||
|
)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleArray, 1
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleMap, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
|
||||||
|
boost::range_detail_microsoft::using_type_as_tag,
|
||||||
|
(ATL, BOOST_PP_NIL), CSimpleValArray, 1
|
||||||
|
)
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
135
boost/range/begin.hpp
Normal file
135
boost/range/begin.hpp
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2003-2004. 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_BEGIN_HPP
|
||||||
|
#define BOOST_RANGE_BEGIN_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
#include <boost/range/detail/begin.hpp>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// primary template
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template< typename C >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
|
||||||
|
range_begin( C& c )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// If you get a compile-error here, it is most likely because
|
||||||
|
// you have not implemented range_begin() properly in
|
||||||
|
// the namespace of C
|
||||||
|
//
|
||||||
|
return c.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// pair
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template< typename Iterator >
|
||||||
|
inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename Iterator >
|
||||||
|
inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// array
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//
|
||||||
|
// May this be discarded? Or is it needed for bad compilers?
|
||||||
|
//
|
||||||
|
template< typename T, std::size_t sz >
|
||||||
|
inline const T* range_begin( const T (&a)[sz] )
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T, std::size_t sz >
|
||||||
|
inline T* range_begin( T (&a)[sz] )
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
} // namespace 'range_detail'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Use a ADL namespace barrier to avoid ambiguity with other unqualified
|
||||||
|
// calls. This is particularly important with C++0x encouraging
|
||||||
|
// unqualified calls to begin/end.
|
||||||
|
namespace range_adl_barrier
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
|
||||||
|
{
|
||||||
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
using namespace range_detail;
|
||||||
|
#endif
|
||||||
|
return range_begin( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
|
||||||
|
{
|
||||||
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
using namespace range_detail;
|
||||||
|
#endif
|
||||||
|
return range_begin( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace range_adl_barrier
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_adl_barrier
|
||||||
|
{
|
||||||
|
template< class T >
|
||||||
|
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
|
||||||
|
const_begin( const T& r )
|
||||||
|
{
|
||||||
|
return boost::range_adl_barrier::begin( r );
|
||||||
|
}
|
||||||
|
} // namespace range_adl_barrier
|
||||||
|
|
||||||
|
using namespace range_adl_barrier;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
29
boost/range/category.hpp
Normal file
29
boost/range/category.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2003-2006. 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_CATEGORY_HPP
|
||||||
|
#define BOOST_RANGE_CATEGORY_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template< class T >
|
||||||
|
struct range_category : iterator_category< typename range_iterator<T>::type >
|
||||||
|
{ };
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
45
boost/range/combine.hpp
Normal file
45
boost/range/combine.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
#include <boost/iterator/zip_iterator.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename IterTuple>
|
||||||
|
class combined_range
|
||||||
|
: public iterator_range<zip_iterator<IterTuple> >
|
||||||
|
{
|
||||||
|
typedef iterator_range<zip_iterator<IterTuple> > base;
|
||||||
|
public:
|
||||||
|
combined_range(IterTuple first, IterTuple last)
|
||||||
|
: base(first, last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \
|
||||||
|
defined(BOOST_NO_CXX11_DECLTYPE) || \
|
||||||
|
defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
|
||||||
|
defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
# include <boost/range/detail/combine_cxx03.hpp>
|
||||||
|
#else
|
||||||
|
# include <boost/range/detail/combine_cxx11.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
386
boost/range/concepts.hpp
Normal file
386
boost/range/concepts.hpp
Normal file
|
@ -0,0 +1,386 @@
|
||||||
|
// Boost.Range library concept checks
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2009. Use, modification and distribution
|
||||||
|
// are 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 Daniel Walker 2006. Use, modification and distribution
|
||||||
|
// are 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_CONCEPTS_HPP
|
||||||
|
#define BOOST_RANGE_CONCEPTS_HPP
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/detail/misc_concept.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
* \brief Concept checks for the Boost Range library.
|
||||||
|
*
|
||||||
|
* The structures in this file may be used in conjunction with the
|
||||||
|
* Boost Concept Check library to insure that the type of a function
|
||||||
|
* parameter is compatible with a range concept. If not, a meaningful
|
||||||
|
* compile time error is generated. Checks are provided for the range
|
||||||
|
* concepts related to iterator traversal categories. For example, the
|
||||||
|
* following line checks that the type T models the ForwardRange
|
||||||
|
* concept.
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* BOOST_CONCEPT_ASSERT((ForwardRangeConcept<T>));
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* A different concept check is required to ensure writeable value
|
||||||
|
* access. For example to check for a ForwardRange that can be written
|
||||||
|
* to, the following code is required.
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept<T>));
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \see http://www.boost.org/libs/range/doc/range.html for details
|
||||||
|
* about range concepts.
|
||||||
|
* \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
|
||||||
|
* for details about iterator concepts.
|
||||||
|
* \see http://www.boost.org/libs/concept_check/concept_check.htm for
|
||||||
|
* details about concept checks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace range_detail {
|
||||||
|
|
||||||
|
#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
|
||||||
|
// List broken compiler versions here:
|
||||||
|
#ifndef __clang__
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
|
||||||
|
// hence the least disruptive approach is to turn-off the concept checking for
|
||||||
|
// this version of the compiler.
|
||||||
|
#if __GNUC__ == 4 && __GNUC_MINOR__ == 2
|
||||||
|
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GCCXML__
|
||||||
|
// GCC XML, unsurprisingly, has the same issues
|
||||||
|
#if __GCCXML_GNUC__ == 4 && __GCCXML_GNUC_MINOR__ == 2
|
||||||
|
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PATHCC__
|
||||||
|
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Default to using the concept asserts unless we have defined it off
|
||||||
|
// during the search for black listed compilers.
|
||||||
|
#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
#define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x )
|
||||||
|
#else
|
||||||
|
#define BOOST_RANGE_CONCEPT_ASSERT( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Rationale for the inclusion of redefined iterator concept
|
||||||
|
// classes:
|
||||||
|
//
|
||||||
|
// The Range algorithms often do not require that the iterators are
|
||||||
|
// 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
|
||||||
|
// use case is the combination of the boost::adaptors::filtered
|
||||||
|
// class with a boost::lambda::bind generated functor.
|
||||||
|
// Ultimately modeling the range concepts using composition
|
||||||
|
// with the Boost.Iterator concepts would render the library
|
||||||
|
// incompatible with many common Boost.Lambda expressions.
|
||||||
|
template<class Iterator>
|
||||||
|
struct IncrementableIteratorConcept : CopyConstructible<Iterator>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator>::type traversal_category;
|
||||||
|
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
Convertible<
|
||||||
|
traversal_category,
|
||||||
|
incrementable_traversal_tag
|
||||||
|
>));
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(IncrementableIteratorConcept)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
(void)i++;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Iterator i;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
struct SinglePassIteratorConcept
|
||||||
|
: IncrementableIteratorConcept<Iterator>
|
||||||
|
, EqualityComparable<Iterator>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
Convertible<
|
||||||
|
BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
|
||||||
|
single_pass_traversal_tag
|
||||||
|
>));
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(SinglePassIteratorConcept)
|
||||||
|
{
|
||||||
|
Iterator i2(++i);
|
||||||
|
boost::ignore_unused_variable_warning(i2);
|
||||||
|
|
||||||
|
// deliberately we are loose with the postfix version for the single pass
|
||||||
|
// iterator due to the commonly poor adherence to the specification means that
|
||||||
|
// many algorithms would be unusable, whereas actually without the check they
|
||||||
|
// work
|
||||||
|
(void)(i++);
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
struct ForwardIteratorConcept
|
||||||
|
: SinglePassIteratorConcept<Iterator>
|
||||||
|
, DefaultConstructible<Iterator>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||||
|
|
||||||
|
BOOST_MPL_ASSERT((is_integral<difference_type>));
|
||||||
|
BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
|
||||||
|
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
Convertible<
|
||||||
|
BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
|
||||||
|
forward_traversal_tag
|
||||||
|
>));
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(ForwardIteratorConcept)
|
||||||
|
{
|
||||||
|
// See the above note in the SinglePassIteratorConcept about the handling of the
|
||||||
|
// postfix increment. Since with forward and better iterators there is no need
|
||||||
|
// for a proxy, we can sensibly require that the dereference result
|
||||||
|
// is convertible to reference.
|
||||||
|
Iterator i2(i++);
|
||||||
|
boost::ignore_unused_variable_warning(i2);
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r(*(i++));
|
||||||
|
boost::ignore_unused_variable_warning(r);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Iterator i;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
struct BidirectionalIteratorConcept
|
||||||
|
: ForwardIteratorConcept<Iterator>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
Convertible<
|
||||||
|
BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category,
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
>));
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept)
|
||||||
|
{
|
||||||
|
--i;
|
||||||
|
(void)i--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Iterator i;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
struct RandomAccessIteratorConcept
|
||||||
|
: BidirectionalIteratorConcept<Iterator>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
Convertible<
|
||||||
|
BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category,
|
||||||
|
random_access_traversal_tag
|
||||||
|
>));
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept)
|
||||||
|
{
|
||||||
|
i += n;
|
||||||
|
i = i + n;
|
||||||
|
i = n + i;
|
||||||
|
i -= n;
|
||||||
|
i = i - n;
|
||||||
|
n = i - j;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n;
|
||||||
|
Iterator i;
|
||||||
|
Iterator j;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
//! Check if a type T models the SinglePassRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct SinglePassRangeConcept
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
// A few compilers don't like the rvalue reference T types so just
|
||||||
|
// remove it.
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type Rng;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<
|
||||||
|
Rng const
|
||||||
|
>::type const_iterator;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type iterator;
|
||||||
|
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
range_detail::SinglePassIteratorConcept<iterator>));
|
||||||
|
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
|
range_detail::SinglePassIteratorConcept<const_iterator>));
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
|
||||||
|
{
|
||||||
|
// This has been modified from assigning to this->i
|
||||||
|
// (where i was a member variable) to improve
|
||||||
|
// compatibility with Boost.Lambda
|
||||||
|
iterator i1 = boost::begin(*m_range);
|
||||||
|
iterator i2 = boost::end(*m_range);
|
||||||
|
|
||||||
|
boost::ignore_unused_variable_warning(i1);
|
||||||
|
boost::ignore_unused_variable_warning(i2);
|
||||||
|
|
||||||
|
const_constraints(*m_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void const_constraints(const Rng& const_range)
|
||||||
|
{
|
||||||
|
const_iterator ci1 = boost::begin(const_range);
|
||||||
|
const_iterator ci2 = boost::end(const_range);
|
||||||
|
|
||||||
|
boost::ignore_unused_variable_warning(ci1);
|
||||||
|
boost::ignore_unused_variable_warning(ci2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rationale:
|
||||||
|
// The type of m_range is T* rather than T because it allows
|
||||||
|
// T to be an abstract class. The other obvious alternative of
|
||||||
|
// T& produces a warning on some compilers.
|
||||||
|
Rng* m_range;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Check if a type T models the ForwardRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct ForwardRangeConcept : SinglePassRangeConcept<T>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::iterator>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::const_iterator>));
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct WriteableRangeConcept
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<T>::type iterator;
|
||||||
|
|
||||||
|
BOOST_CONCEPT_USAGE(WriteableRangeConcept)
|
||||||
|
{
|
||||||
|
*i = v;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
iterator i;
|
||||||
|
BOOST_DEDUCED_TYPENAME range_value<T>::type v;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Check if a type T models the WriteableForwardRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct WriteableForwardRangeConcept
|
||||||
|
: ForwardRangeConcept<T>
|
||||||
|
, WriteableRangeConcept<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Check if a type T models the BidirectionalRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct BidirectionalRangeConcept : ForwardRangeConcept<T>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::iterator>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::const_iterator>));
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Check if a type T models the WriteableBidirectionalRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct WriteableBidirectionalRangeConcept
|
||||||
|
: BidirectionalRangeConcept<T>
|
||||||
|
, WriteableRangeConcept<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Check if a type T models the RandomAccessRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct RandomAccessRangeConcept : BidirectionalRangeConcept<T>
|
||||||
|
{
|
||||||
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::iterator>));
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::const_iterator>));
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Check if a type T models the WriteableRandomAccessRange range concept.
|
||||||
|
template<class T>
|
||||||
|
struct WriteableRandomAccessRangeConcept
|
||||||
|
: RandomAccessRangeConcept<T>
|
||||||
|
, WriteableRangeConcept<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_RANGE_CONCEPTS_HPP
|
56
boost/range/config.hpp
Normal file
56
boost/range/config.hpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2003-2004. 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_CONFIG_HPP
|
||||||
|
#define BOOST_RANGE_CONFIG_HPP
|
||||||
|
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_RANGE_DEDUCED_TYPENAME
|
||||||
|
#error "macro already defined!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
# define BOOST_RANGE_DEDUCED_TYPENAME typename
|
||||||
|
#else
|
||||||
|
#define BOOST_RANGE_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
|
||||||
|
#error "macro already defined!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
|
||||||
|
#define BOOST_RANGE_NO_ARRAY_SUPPORT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
|
||||||
|
#define BOOST_RANGE_ARRAY_REF() (boost_range_array)
|
||||||
|
#define BOOST_RANGE_NO_STATIC_ASSERT
|
||||||
|
#else
|
||||||
|
#define BOOST_RANGE_ARRAY_REF() (&boost_range_array)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
|
||||||
|
# define BOOST_RANGE_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
# define BOOST_RANGE_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
76
boost/range/const_iterator.hpp
Normal file
76
boost/range/const_iterator.hpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2003-2004. 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_CONST_ITERATOR_HPP
|
||||||
|
#define BOOST_RANGE_CONST_ITERATOR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
|
||||||
|
#include <boost/range/range_fwd.hpp>
|
||||||
|
#include <boost/range/detail/extract_optional_type.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// default
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator )
|
||||||
|
|
||||||
|
template< typename C >
|
||||||
|
struct range_const_iterator
|
||||||
|
: extract_const_iterator<C>
|
||||||
|
{};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// pair
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template< typename Iterator >
|
||||||
|
struct range_const_iterator<std::pair<Iterator,Iterator> >
|
||||||
|
{
|
||||||
|
typedef Iterator type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// array
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template< typename T, std::size_t sz >
|
||||||
|
struct range_const_iterator< T[sz] >
|
||||||
|
{
|
||||||
|
typedef const T* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
template<typename C, typename Enabler=void>
|
||||||
|
struct range_const_iterator
|
||||||
|
: range_detail::range_const_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME remove_reference<C>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
35
boost/range/const_reverse_iterator.hpp
Normal file
35
boost/range/const_reverse_iterator.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Thorsten Ottosen 2003-2004. 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_CONST_REVERSE_ITERATOR_HPP
|
||||||
|
#define BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/reverse_iterator.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// This interface is deprecated, use range_reverse_iterator<const T>
|
||||||
|
//
|
||||||
|
|
||||||
|
template< typename C >
|
||||||
|
struct range_const_reverse_iterator
|
||||||
|
: range_reverse_iterator<
|
||||||
|
const BOOST_DEDUCED_TYPENAME remove_reference<C>::type>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
76
boost/range/counting_range.hpp
Normal file
76
boost/range/counting_range.hpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// 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_COUNTING_RANGE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if BOOST_MSVC >= 1400
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/iterator/counting_iterator.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template<class Value>
|
||||||
|
inline iterator_range<counting_iterator<Value> >
|
||||||
|
counting_range(Value first, Value last)
|
||||||
|
{
|
||||||
|
typedef counting_iterator<Value> counting_iterator_t;
|
||||||
|
typedef iterator_range<counting_iterator_t> result_t;
|
||||||
|
return result_t(counting_iterator_t(first),
|
||||||
|
counting_iterator_t(last));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Range>
|
||||||
|
inline iterator_range<
|
||||||
|
counting_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
counting_range(const Range& rng)
|
||||||
|
{
|
||||||
|
typedef counting_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type
|
||||||
|
> counting_iterator_t;
|
||||||
|
|
||||||
|
typedef iterator_range<counting_iterator_t> result_t;
|
||||||
|
|
||||||
|
return result_t(counting_iterator_t(boost::begin(rng)),
|
||||||
|
counting_iterator_t(boost::end(rng)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Range>
|
||||||
|
inline iterator_range<
|
||||||
|
counting_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
counting_range(Range& rng)
|
||||||
|
{
|
||||||
|
typedef counting_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
|
||||||
|
> counting_iterator_t;
|
||||||
|
|
||||||
|
typedef iterator_range<counting_iterator_t> result_t;
|
||||||
|
|
||||||
|
return result_t(counting_iterator_t(boost::begin(rng)),
|
||||||
|
counting_iterator_t(boost::end(rng)));
|
||||||
|
}
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#if BOOST_MSVC >= 1400
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // include guard
|
587
boost/range/detail/any_iterator.hpp
Normal file
587
boost/range/detail/any_iterator.hpp
Normal file
|
@ -0,0 +1,587 @@
|
||||||
|
// 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_DETAIL_ANY_ITERATOR_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/mpl/or.hpp>
|
||||||
|
#include <boost/mpl/not.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
#include <boost/range/detail/any_iterator_buffer.hpp>
|
||||||
|
#include <boost/range/detail/any_iterator_interface.hpp>
|
||||||
|
#include <boost/range/detail/any_iterator_wrapper.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
// metafunction to determine if T is a const reference
|
||||||
|
template<class T>
|
||||||
|
struct is_const_reference
|
||||||
|
{
|
||||||
|
typedef typename mpl::and_<
|
||||||
|
typename is_reference<T>::type,
|
||||||
|
typename is_const<
|
||||||
|
typename remove_reference<T>::type
|
||||||
|
>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// metafunction to determine if T is a mutable reference
|
||||||
|
template<class T>
|
||||||
|
struct is_mutable_reference
|
||||||
|
{
|
||||||
|
typedef typename mpl::and_<
|
||||||
|
typename is_reference<T>::type,
|
||||||
|
typename mpl::not_<
|
||||||
|
typename is_const<
|
||||||
|
typename remove_reference<T>::type
|
||||||
|
>::type
|
||||||
|
>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// metafunction to evaluate if a source 'reference' can be
|
||||||
|
// converted to a target 'reference' as a value.
|
||||||
|
//
|
||||||
|
// This is true, when the target reference type is actually
|
||||||
|
// not a reference, and the source reference is convertible
|
||||||
|
// to the target type.
|
||||||
|
template<class SourceReference, class TargetReference>
|
||||||
|
struct is_convertible_to_value_as_reference
|
||||||
|
{
|
||||||
|
typedef typename mpl::and_<
|
||||||
|
typename mpl::not_<
|
||||||
|
typename is_reference<TargetReference>::type
|
||||||
|
>::type
|
||||||
|
, typename is_convertible<
|
||||||
|
SourceReference
|
||||||
|
, TargetReference
|
||||||
|
>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer = any_iterator_default_buffer
|
||||||
|
>
|
||||||
|
class any_iterator;
|
||||||
|
|
||||||
|
// metafunction to determine if SomeIterator is an
|
||||||
|
// any_iterator.
|
||||||
|
//
|
||||||
|
// This is the general implementation which evaluates to false.
|
||||||
|
template<class SomeIterator>
|
||||||
|
struct is_any_iterator
|
||||||
|
: mpl::bool_<false>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// specialization of is_any_iterator to return true for
|
||||||
|
// any_iterator classes regardless of template parameters.
|
||||||
|
template<
|
||||||
|
class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct is_any_iterator<
|
||||||
|
any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
>
|
||||||
|
: mpl::bool_<true>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
// Rationale:
|
||||||
|
// These are specialized since the iterator_facade versions lack
|
||||||
|
// the requisite typedefs to allow wrapping to determine the types
|
||||||
|
// if a user copy constructs from a postfix increment.
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class postfix_increment_proxy<
|
||||||
|
range_detail::any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef range_detail::any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> any_iterator_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Value value_type;
|
||||||
|
typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
|
||||||
|
typedef Difference difference_type;
|
||||||
|
typedef typename iterator_pointer<any_iterator_type>::type pointer;
|
||||||
|
typedef Reference reference;
|
||||||
|
|
||||||
|
explicit postfix_increment_proxy(any_iterator_type const& x)
|
||||||
|
: stored_value(*x)
|
||||||
|
{}
|
||||||
|
|
||||||
|
value_type&
|
||||||
|
operator*() const
|
||||||
|
{
|
||||||
|
return this->stored_value;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
mutable value_type stored_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class writable_postfix_increment_proxy<
|
||||||
|
range_detail::any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef range_detail::any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> any_iterator_type;
|
||||||
|
public:
|
||||||
|
typedef Value value_type;
|
||||||
|
typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
|
||||||
|
typedef Difference difference_type;
|
||||||
|
typedef typename iterator_pointer<any_iterator_type>::type pointer;
|
||||||
|
typedef Reference reference;
|
||||||
|
|
||||||
|
explicit writable_postfix_increment_proxy(any_iterator_type const& x)
|
||||||
|
: stored_value(*x)
|
||||||
|
, stored_iterator(x)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Dereferencing must return a proxy so that both *r++ = o and
|
||||||
|
// value_type(*r++) can work. In this case, *r is the same as
|
||||||
|
// *r++, and the conversion operator below is used to ensure
|
||||||
|
// readability.
|
||||||
|
writable_postfix_increment_proxy const&
|
||||||
|
operator*() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provides readability of *r++
|
||||||
|
operator value_type&() const
|
||||||
|
{
|
||||||
|
return stored_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provides writability of *r++
|
||||||
|
template <class T>
|
||||||
|
T const& operator=(T const& x) const
|
||||||
|
{
|
||||||
|
*this->stored_iterator = x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This overload just in case only non-const objects are writable
|
||||||
|
template <class T>
|
||||||
|
T& operator=(T& x) const
|
||||||
|
{
|
||||||
|
*this->stored_iterator = x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provides X(r++)
|
||||||
|
operator any_iterator_type const&() const
|
||||||
|
{
|
||||||
|
return stored_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable value_type stored_value;
|
||||||
|
any_iterator_type stored_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template<
|
||||||
|
class Value
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class any_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
>
|
||||||
|
{
|
||||||
|
template<
|
||||||
|
class OtherValue
|
||||||
|
, class OtherTraversal
|
||||||
|
, class OtherReference
|
||||||
|
, class OtherDifference
|
||||||
|
, class OtherBuffer
|
||||||
|
>
|
||||||
|
friend class any_iterator;
|
||||||
|
|
||||||
|
struct enabler {};
|
||||||
|
struct disabler {};
|
||||||
|
|
||||||
|
typedef typename any_iterator_interface_type_generator<
|
||||||
|
Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type abstract_base_type;
|
||||||
|
|
||||||
|
typedef iterator_facade<
|
||||||
|
any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
, Value
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
typedef Buffer buffer_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_type::value_type value_type;
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
typedef typename base_type::difference_type difference_type;
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
any_iterator()
|
||||||
|
: m_impl(0) {}
|
||||||
|
|
||||||
|
// Simple copy construction without conversion
|
||||||
|
any_iterator(const any_iterator& other)
|
||||||
|
: base_type(other)
|
||||||
|
, m_impl(other.m_impl
|
||||||
|
? other.m_impl->clone(m_buffer)
|
||||||
|
: 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple assignment operator without conversion
|
||||||
|
any_iterator& operator=(const any_iterator& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
if (m_impl)
|
||||||
|
m_impl->~abstract_base_type();
|
||||||
|
m_buffer.deallocate();
|
||||||
|
m_impl = 0;
|
||||||
|
if (other.m_impl)
|
||||||
|
m_impl = other.m_impl->clone(m_buffer);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implicit conversion from another any_iterator where the
|
||||||
|
// conversion is from a non-const reference to a const reference
|
||||||
|
template<
|
||||||
|
class OtherValue
|
||||||
|
, class OtherTraversal
|
||||||
|
, class OtherReference
|
||||||
|
, class OtherDifference
|
||||||
|
>
|
||||||
|
any_iterator(const any_iterator<
|
||||||
|
OtherValue,
|
||||||
|
OtherTraversal,
|
||||||
|
OtherReference,
|
||||||
|
OtherDifference,
|
||||||
|
Buffer
|
||||||
|
>& other,
|
||||||
|
typename ::boost::enable_if<
|
||||||
|
typename mpl::and_<
|
||||||
|
typename is_mutable_reference<OtherReference>::type,
|
||||||
|
typename is_const_reference<Reference>::type
|
||||||
|
>::type,
|
||||||
|
enabler
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
: m_impl(other.m_impl
|
||||||
|
? other.m_impl->clone_const_ref(m_buffer)
|
||||||
|
: 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implicit conversion from another any_iterator where the
|
||||||
|
// reference types of the source and the target are references
|
||||||
|
// that are either both const, or both non-const.
|
||||||
|
template<
|
||||||
|
class OtherValue
|
||||||
|
, class OtherTraversal
|
||||||
|
, class OtherReference
|
||||||
|
, class OtherDifference
|
||||||
|
>
|
||||||
|
any_iterator(const any_iterator<
|
||||||
|
OtherValue
|
||||||
|
, OtherTraversal
|
||||||
|
, OtherReference
|
||||||
|
, OtherDifference
|
||||||
|
, Buffer
|
||||||
|
>& other,
|
||||||
|
typename ::boost::enable_if<
|
||||||
|
typename mpl::or_<
|
||||||
|
typename mpl::and_<
|
||||||
|
typename is_mutable_reference<OtherReference>::type,
|
||||||
|
typename is_mutable_reference<Reference>::type
|
||||||
|
>::type,
|
||||||
|
typename mpl::and_<
|
||||||
|
typename is_const_reference<OtherReference>::type,
|
||||||
|
typename is_const_reference<Reference>::type
|
||||||
|
>::type
|
||||||
|
>::type,
|
||||||
|
enabler
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
: m_impl(other.m_impl
|
||||||
|
? other.m_impl->clone(m_buffer)
|
||||||
|
: 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implicit conversion to an any_iterator that uses a value for
|
||||||
|
// the reference type.
|
||||||
|
template<
|
||||||
|
class OtherValue
|
||||||
|
, class OtherTraversal
|
||||||
|
, class OtherReference
|
||||||
|
, class OtherDifference
|
||||||
|
>
|
||||||
|
any_iterator(const any_iterator<
|
||||||
|
OtherValue
|
||||||
|
, OtherTraversal
|
||||||
|
, OtherReference
|
||||||
|
, OtherDifference
|
||||||
|
, Buffer
|
||||||
|
>& other,
|
||||||
|
typename ::boost::enable_if<
|
||||||
|
typename is_convertible_to_value_as_reference<
|
||||||
|
OtherReference
|
||||||
|
, Reference
|
||||||
|
>::type,
|
||||||
|
enabler
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
: m_impl(other.m_impl
|
||||||
|
? other.m_impl->clone_reference_as_value(m_buffer)
|
||||||
|
: 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
any_iterator clone() const
|
||||||
|
{
|
||||||
|
any_iterator result;
|
||||||
|
if (m_impl)
|
||||||
|
result.m_impl = m_impl->clone(result.m_buffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, typename abstract_base_type::const_reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
clone_const_ref() const
|
||||||
|
{
|
||||||
|
typedef any_iterator<
|
||||||
|
Value
|
||||||
|
, Traversal
|
||||||
|
, typename abstract_base_type::const_reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
result_type result;
|
||||||
|
|
||||||
|
if (m_impl)
|
||||||
|
result.m_impl = m_impl->clone_const_ref(result.m_buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// implicit conversion and construction from type-erasure-compatible
|
||||||
|
// iterators
|
||||||
|
template<class WrappedIterator>
|
||||||
|
explicit any_iterator(
|
||||||
|
const WrappedIterator& wrapped_iterator,
|
||||||
|
typename disable_if<
|
||||||
|
typename is_any_iterator<WrappedIterator>::type
|
||||||
|
, disabler
|
||||||
|
>::type* = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef typename any_iterator_wrapper_type_generator<
|
||||||
|
WrappedIterator
|
||||||
|
, Traversal
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>::type wrapper_type;
|
||||||
|
|
||||||
|
void* ptr = m_buffer.allocate(sizeof(wrapper_type));
|
||||||
|
m_impl = new(ptr) wrapper_type(wrapped_iterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
~any_iterator()
|
||||||
|
{
|
||||||
|
// manually run the destructor, the deallocation is automatically
|
||||||
|
// handled by the any_iterator_small_buffer base class.
|
||||||
|
if (m_impl)
|
||||||
|
m_impl->~abstract_base_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class ::boost::iterator_core_access;
|
||||||
|
|
||||||
|
Reference dereference() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( m_impl );
|
||||||
|
return m_impl->dereference();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(const any_iterator& other) const
|
||||||
|
{
|
||||||
|
return (m_impl == other.m_impl)
|
||||||
|
|| (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( m_impl );
|
||||||
|
m_impl->increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( m_impl );
|
||||||
|
m_impl->decrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
Difference distance_to(const any_iterator& other) const
|
||||||
|
{
|
||||||
|
return m_impl && other.m_impl
|
||||||
|
? m_impl->distance_to(*other.m_impl)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance(Difference offset)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( m_impl );
|
||||||
|
m_impl->advance(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
any_iterator& swap(any_iterator& other)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( this != &other );
|
||||||
|
// grab a temporary copy of the other iterator
|
||||||
|
any_iterator tmp(other);
|
||||||
|
|
||||||
|
// deallocate the other iterator, taking care to obey the
|
||||||
|
// class-invariants in-case of exceptions later
|
||||||
|
if (other.m_impl)
|
||||||
|
{
|
||||||
|
other.m_impl->~abstract_base_type();
|
||||||
|
other.m_buffer.deallocate();
|
||||||
|
other.m_impl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a non-null iterator then we need to put
|
||||||
|
// a clone of this iterators implementation into the other
|
||||||
|
// iterator.
|
||||||
|
// We can't just swap because of the small buffer optimization.
|
||||||
|
if (m_impl)
|
||||||
|
{
|
||||||
|
other.m_impl = m_impl->clone(other.m_buffer);
|
||||||
|
m_impl->~abstract_base_type();
|
||||||
|
m_buffer.deallocate();
|
||||||
|
m_impl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign to this instance a clone of the temporarily held
|
||||||
|
// tmp which represents the input other parameter at the
|
||||||
|
// start of execution of this function.
|
||||||
|
if (tmp.m_impl)
|
||||||
|
m_impl = tmp.m_impl->clone(m_buffer);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_type m_buffer;
|
||||||
|
abstract_base_type* m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
117
boost/range/detail/any_iterator_buffer.hpp
Normal file
117
boost/range/detail/any_iterator_buffer.hpp
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
// 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_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template<std::size_t StackBufferSize>
|
||||||
|
class any_iterator_buffer
|
||||||
|
: noncopyable
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
|
||||||
|
public:
|
||||||
|
any_iterator_buffer()
|
||||||
|
: m_ptr()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~any_iterator_buffer()
|
||||||
|
{
|
||||||
|
delete [] m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* allocate(std::size_t bytes)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( !m_ptr );
|
||||||
|
if (bytes <= StackBufferSize)
|
||||||
|
return m_buffer.data();
|
||||||
|
|
||||||
|
m_ptr = new char[bytes];
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate()
|
||||||
|
{
|
||||||
|
delete [] m_ptr;
|
||||||
|
m_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Rationale:
|
||||||
|
// Do not use inheritance from noncopyable because this causes
|
||||||
|
// the concepts to erroneous detect the derived any_iterator
|
||||||
|
// as noncopyable.
|
||||||
|
any_iterator_buffer(const any_iterator_buffer&);
|
||||||
|
void operator=(const any_iterator_buffer&);
|
||||||
|
|
||||||
|
char* m_ptr;
|
||||||
|
boost::array<char, StackBufferSize> m_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
class any_iterator_heap_only_buffer
|
||||||
|
: noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
any_iterator_heap_only_buffer()
|
||||||
|
: m_ptr()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~any_iterator_heap_only_buffer()
|
||||||
|
{
|
||||||
|
delete [] m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* allocate(std::size_t bytes)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( !m_ptr );
|
||||||
|
m_ptr = new char[bytes];
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate()
|
||||||
|
{
|
||||||
|
delete [] m_ptr;
|
||||||
|
m_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t StackBufferSize>
|
||||||
|
class any_iterator_stack_only_buffer
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
|
||||||
|
public:
|
||||||
|
void* allocate(std::size_t bytes)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( bytes <= m_buffer.size() );
|
||||||
|
return m_buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::array<char, StackBufferSize> m_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef any_iterator_buffer<64> any_iterator_default_buffer;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
277
boost/range/detail/any_iterator_interface.hpp
Normal file
277
boost/range/detail/any_iterator_interface.hpp
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
// 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_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/range/detail/any_iterator_buffer.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/type_traits/add_const.hpp>
|
||||||
|
#include <boost/type_traits/add_reference.hpp>
|
||||||
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
struct const_reference_type_generator
|
||||||
|
{
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
typename is_reference<T>::type,
|
||||||
|
typename add_const<
|
||||||
|
typename remove_reference<T>::type
|
||||||
|
>::type&,
|
||||||
|
T
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct mutable_reference_type_generator
|
||||||
|
{
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
typename mpl::and_<
|
||||||
|
typename is_const<T>::type,
|
||||||
|
typename mpl::not_<typename is_reference<T>::type>::type
|
||||||
|
>::type,
|
||||||
|
T,
|
||||||
|
typename add_reference<T>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_incrementable_iterator_interface
|
||||||
|
{
|
||||||
|
typedef typename mutable_reference_type_generator<
|
||||||
|
Reference
|
||||||
|
>::type reference;
|
||||||
|
|
||||||
|
typedef typename const_reference_type_generator<
|
||||||
|
Reference
|
||||||
|
>::type const_reference;
|
||||||
|
|
||||||
|
typedef typename remove_const<
|
||||||
|
typename remove_reference<Reference>::type
|
||||||
|
>::type reference_as_value_type;
|
||||||
|
|
||||||
|
typedef Buffer buffer_type;
|
||||||
|
|
||||||
|
virtual ~any_incrementable_iterator_interface() {}
|
||||||
|
|
||||||
|
virtual any_incrementable_iterator_interface*
|
||||||
|
clone(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_incrementable_iterator_interface<const_reference, Buffer>*
|
||||||
|
clone_const_ref(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_incrementable_iterator_interface<reference_as_value_type, Buffer>*
|
||||||
|
clone_reference_as_value(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual void increment() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_single_pass_iterator_interface
|
||||||
|
: any_incrementable_iterator_interface<Reference, Buffer>
|
||||||
|
{
|
||||||
|
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference reference;
|
||||||
|
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::const_reference const_reference;
|
||||||
|
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
|
||||||
|
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
|
||||||
|
|
||||||
|
virtual any_single_pass_iterator_interface*
|
||||||
|
clone(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_single_pass_iterator_interface<const_reference, Buffer>*
|
||||||
|
clone_const_ref(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
|
||||||
|
clone_reference_as_value(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual reference dereference() const = 0;
|
||||||
|
|
||||||
|
virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_forward_iterator_interface
|
||||||
|
: any_single_pass_iterator_interface<Reference, Buffer>
|
||||||
|
{
|
||||||
|
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference reference;
|
||||||
|
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::const_reference const_reference;
|
||||||
|
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
|
||||||
|
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
|
||||||
|
|
||||||
|
virtual any_forward_iterator_interface*
|
||||||
|
clone(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_forward_iterator_interface<const_reference, Buffer>*
|
||||||
|
clone_const_ref(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_forward_iterator_interface<reference_as_value_type, Buffer>*
|
||||||
|
clone_reference_as_value(buffer_type& buffer) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_bidirectional_iterator_interface
|
||||||
|
: any_forward_iterator_interface<Reference, Buffer>
|
||||||
|
{
|
||||||
|
typedef typename any_forward_iterator_interface<Reference, Buffer>::reference reference;
|
||||||
|
typedef typename any_forward_iterator_interface<Reference, Buffer>::const_reference const_reference;
|
||||||
|
typedef typename any_forward_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
|
||||||
|
typedef typename any_forward_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
|
||||||
|
|
||||||
|
virtual any_bidirectional_iterator_interface*
|
||||||
|
clone(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_bidirectional_iterator_interface<const_reference, Buffer>*
|
||||||
|
clone_const_ref(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_bidirectional_iterator_interface<reference_as_value_type, Buffer>*
|
||||||
|
clone_reference_as_value(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual void decrement() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_random_access_iterator_interface
|
||||||
|
: any_bidirectional_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference reference;
|
||||||
|
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::const_reference const_reference;
|
||||||
|
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
|
||||||
|
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
|
||||||
|
typedef Difference difference_type;
|
||||||
|
|
||||||
|
virtual any_random_access_iterator_interface*
|
||||||
|
clone(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_random_access_iterator_interface<const_reference, Difference, Buffer>*
|
||||||
|
clone_const_ref(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual any_random_access_iterator_interface<reference_as_value_type, Difference, Buffer>*
|
||||||
|
clone_reference_as_value(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
|
virtual void advance(Difference offset) = 0;
|
||||||
|
|
||||||
|
virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_interface_type_generator;
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_interface_type_generator<
|
||||||
|
incrementable_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_incrementable_iterator_interface<Reference, Buffer> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_interface_type_generator<
|
||||||
|
single_pass_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_single_pass_iterator_interface<Reference, Buffer> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_interface_type_generator<
|
||||||
|
forward_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_forward_iterator_interface<Reference, Buffer> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_interface_type_generator<
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_bidirectional_iterator_interface<Reference, Buffer> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_interface_type_generator<
|
||||||
|
random_access_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_random_access_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
640
boost/range/detail/any_iterator_wrapper.hpp
Normal file
640
boost/range/detail/any_iterator_wrapper.hpp
Normal file
|
@ -0,0 +1,640 @@
|
||||||
|
// 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_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
|
||||||
|
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/polymorphic_cast.hpp>
|
||||||
|
#include <boost/range/config.hpp>
|
||||||
|
#include <boost/range/detail/any_iterator_interface.hpp>
|
||||||
|
#include <boost/range/concepts.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template<typename TargetT, typename SourceT>
|
||||||
|
TargetT& polymorphic_ref_downcast(SourceT& source)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_NO_RTTI
|
||||||
|
return static_cast<TargetT&>(source);
|
||||||
|
#else
|
||||||
|
return *boost::polymorphic_downcast<TargetT*>(&source);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Reference, class T>
|
||||||
|
Reference dereference_cast(T& x)
|
||||||
|
{
|
||||||
|
return static_cast<Reference>(x);
|
||||||
|
}
|
||||||
|
template<class Reference, class T>
|
||||||
|
Reference dereference_cast(const T& x)
|
||||||
|
{
|
||||||
|
return static_cast<Reference>(const_cast<T&>(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class any_incrementable_iterator_wrapper
|
||||||
|
: public any_incrementable_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept<WrappedIterator> ));
|
||||||
|
public:
|
||||||
|
typedef WrappedIterator wrapped_type;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(( is_convertible<
|
||||||
|
typename iterator_reference<WrappedIterator>::type
|
||||||
|
, Reference
|
||||||
|
>::value ));
|
||||||
|
|
||||||
|
any_incrementable_iterator_wrapper()
|
||||||
|
: m_it()
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit any_incrementable_iterator_wrapper(wrapped_type it)
|
||||||
|
: m_it(it)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// any_incrementable_iterator implementation
|
||||||
|
virtual any_incrementable_iterator_wrapper* clone(
|
||||||
|
typename any_incrementable_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return new (buffer.allocate(sizeof(*this)))
|
||||||
|
any_incrementable_iterator_wrapper(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_incrementable_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_incrementable_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
>* clone_const_ref(
|
||||||
|
typename any_incrementable_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_incrementable_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_incrementable_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_incrementable_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_incrementable_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
>* clone_reference_as_value(
|
||||||
|
typename any_incrementable_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_incrementable_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_incrementable_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wrapped_type m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class any_single_pass_iterator_wrapper
|
||||||
|
: public any_single_pass_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
struct disabler {};
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_single_pass_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
|
||||||
|
any_single_pass_iterator_wrapper()
|
||||||
|
: m_it()
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit any_single_pass_iterator_wrapper(const WrappedIterator& it)
|
||||||
|
: m_it(it)
|
||||||
|
{}
|
||||||
|
// any_single_pass_iterator_interface<Reference> implementation
|
||||||
|
virtual any_single_pass_iterator_wrapper* clone(
|
||||||
|
typename any_single_pass_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return new (buffer.allocate(sizeof(*this)))
|
||||||
|
any_single_pass_iterator_wrapper(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_single_pass_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_single_pass_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
>* clone_const_ref(
|
||||||
|
typename any_single_pass_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_single_pass_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_single_pass_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_single_pass_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_single_pass_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
>* clone_reference_as_value(
|
||||||
|
typename any_single_pass_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_single_pass_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_single_pass_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
|
||||||
|
{
|
||||||
|
return m_it == range_detail::polymorphic_ref_downcast<const any_single_pass_iterator_wrapper>(other).m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual reference dereference() const
|
||||||
|
{
|
||||||
|
return dereference_cast<reference>(*m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
WrappedIterator m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class any_forward_iterator_wrapper
|
||||||
|
: public any_forward_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_forward_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
|
||||||
|
any_forward_iterator_wrapper()
|
||||||
|
: m_it()
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit any_forward_iterator_wrapper(const WrappedIterator& it)
|
||||||
|
: m_it(it)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// any_forward_iterator_interface<Reference> implementation
|
||||||
|
virtual any_forward_iterator_wrapper* clone(
|
||||||
|
typename any_forward_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return new (buffer.allocate(sizeof(*this)))
|
||||||
|
any_forward_iterator_wrapper(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_forward_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_forward_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
>* clone_const_ref(
|
||||||
|
typename any_forward_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_forward_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_forward_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_forward_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_forward_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
>* clone_reference_as_value(
|
||||||
|
typename any_forward_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_forward_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_forward_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
|
||||||
|
{
|
||||||
|
return m_it == range_detail::polymorphic_ref_downcast<const any_forward_iterator_wrapper>(other).m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual reference dereference() const
|
||||||
|
{
|
||||||
|
return dereference_cast<reference>(*m_it);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
WrappedIterator m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class any_bidirectional_iterator_wrapper
|
||||||
|
: public any_bidirectional_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_bidirectional_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
|
||||||
|
any_bidirectional_iterator_wrapper()
|
||||||
|
: m_it()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it)
|
||||||
|
: m_it(it)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_bidirectional_iterator_wrapper* clone(
|
||||||
|
typename any_bidirectional_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return new (buffer.allocate(sizeof(*this)))
|
||||||
|
any_bidirectional_iterator_wrapper(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_bidirectional_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_bidirectional_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
>* clone_const_ref(
|
||||||
|
typename any_bidirectional_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_bidirectional_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_bidirectional_iterator_wrapper::const_reference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_bidirectional_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_bidirectional_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
>* clone_reference_as_value(
|
||||||
|
typename any_bidirectional_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_bidirectional_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_bidirectional_iterator_wrapper::reference_as_value_type
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void decrement()
|
||||||
|
{
|
||||||
|
--m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
|
||||||
|
{
|
||||||
|
return m_it == range_detail::polymorphic_ref_downcast<const any_bidirectional_iterator_wrapper>(other).m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual reference dereference() const
|
||||||
|
{
|
||||||
|
return dereference_cast<reference>(*m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
WrappedIterator m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
class any_random_access_iterator_wrapper
|
||||||
|
: public any_random_access_iterator_interface<
|
||||||
|
Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_random_access_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Difference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
typedef Difference difference_type;
|
||||||
|
|
||||||
|
any_random_access_iterator_wrapper()
|
||||||
|
: m_it()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit any_random_access_iterator_wrapper(const WrappedIterator& other)
|
||||||
|
: m_it(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_random_access_iterator_wrapper* clone(
|
||||||
|
typename any_random_access_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return new (buffer.allocate(sizeof(*this)))
|
||||||
|
any_random_access_iterator_wrapper(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_random_access_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_random_access_iterator_wrapper::const_reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>* clone_const_ref(
|
||||||
|
typename any_random_access_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_random_access_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_random_access_iterator_wrapper::const_reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual any_random_access_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_random_access_iterator_wrapper::reference_as_value_type
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>* clone_reference_as_value(
|
||||||
|
typename any_random_access_iterator_wrapper::buffer_type& buffer
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef any_random_access_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, typename any_random_access_iterator_wrapper::reference_as_value_type
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> result_type;
|
||||||
|
|
||||||
|
return new (buffer.allocate(sizeof(result_type)))
|
||||||
|
result_type(m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
|
||||||
|
{
|
||||||
|
return m_it == range_detail::polymorphic_ref_downcast<const any_random_access_iterator_wrapper>(other).m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void decrement()
|
||||||
|
{
|
||||||
|
--m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void advance(Difference offset)
|
||||||
|
{
|
||||||
|
m_it += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual reference dereference() const
|
||||||
|
{
|
||||||
|
return dereference_cast<reference>(*m_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
|
||||||
|
{
|
||||||
|
return range_detail::polymorphic_ref_downcast<const any_random_access_iterator_wrapper>(other).m_it - m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
WrappedIterator m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Traversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_wrapper_type_generator;
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_wrapper_type_generator<
|
||||||
|
WrappedIterator
|
||||||
|
, incrementable_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_incrementable_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, Reference
|
||||||
|
, Buffer
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_wrapper_type_generator<
|
||||||
|
WrappedIterator
|
||||||
|
, single_pass_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_single_pass_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, Reference
|
||||||
|
, Buffer
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_wrapper_type_generator<
|
||||||
|
WrappedIterator
|
||||||
|
, forward_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_forward_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, Reference
|
||||||
|
, Buffer
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_wrapper_type_generator<
|
||||||
|
WrappedIterator
|
||||||
|
, bidirectional_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_bidirectional_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, Reference
|
||||||
|
, Buffer
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
class WrappedIterator
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, class Buffer
|
||||||
|
>
|
||||||
|
struct any_iterator_wrapper_type_generator<
|
||||||
|
WrappedIterator
|
||||||
|
, random_access_traversal_tag
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef any_random_access_iterator_wrapper<
|
||||||
|
WrappedIterator
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
, Buffer
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // include guard
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue