整理
This commit is contained in:
237
include/boost/range/adaptor/adjacent_filtered.hpp
Normal file
237
include/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, const 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
include/boost/range/adaptor/argument_fwd.hpp
Normal file
80
include/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
include/boost/range/adaptor/copied.hpp
Normal file
68
include/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
include/boost/range/adaptor/define_adaptor.hpp
Normal file
109
include/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
|
||||
121
include/boost/range/adaptor/filtered.hpp
Normal file
121
include/boost/range/adaptor/filtered.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
// 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 SinglePassRange, class Predicate >
|
||||
inline filtered_range<Predicate, SinglePassRange>
|
||||
operator|(SinglePassRange& r,
|
||||
const filter_holder<Predicate>& f)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
|
||||
return filtered_range<Predicate, SinglePassRange>( f.val, r );
|
||||
}
|
||||
|
||||
template< class SinglePassRange, class Predicate >
|
||||
inline filtered_range<Predicate, const SinglePassRange>
|
||||
operator|(const SinglePassRange& r,
|
||||
const filter_holder<Predicate>& f )
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<const SinglePassRange>));
|
||||
return filtered_range<Predicate, const SinglePassRange>( 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 SinglePassRange, class Predicate>
|
||||
inline filtered_range<Predicate, SinglePassRange>
|
||||
filter(SinglePassRange& rng, Predicate filter_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return range_detail::filtered_range<
|
||||
Predicate, SinglePassRange>( filter_pred, rng );
|
||||
}
|
||||
|
||||
template<class SinglePassRange, class Predicate>
|
||||
inline filtered_range<Predicate, const SinglePassRange>
|
||||
filter(const SinglePassRange& rng, Predicate filter_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<const SinglePassRange>));
|
||||
|
||||
return range_detail::filtered_range<
|
||||
Predicate, const SinglePassRange>( filter_pred, rng );
|
||||
}
|
||||
} // 'adaptors'
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
229
include/boost/range/adaptor/formatted.hpp
Normal file
229
include/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
|
||||
395
include/boost/range/adaptor/indexed.hpp
Normal file
395
include/boost/range/adaptor/indexed.hpp
Normal file
@@ -0,0 +1,395 @@
|
||||
// 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
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
namespace std {
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wmismatched-tags"
|
||||
#endif
|
||||
|
||||
template<size_t N, class T, class Indexable>
|
||||
struct tuple_element<N, boost::range::index_value<T, Indexable>>:
|
||||
boost::tuples::element<N, boost::range::index_value<T, Indexable>> {};
|
||||
|
||||
template<class T, class Indexable>
|
||||
struct tuple_size<boost::range::index_value<T, Indexable>>:
|
||||
std::integral_constant<std::size_t, 2> {};
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
#endif // include guard
|
||||
100
include/boost/range/adaptor/indirected.hpp
Normal file
100
include/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
include/boost/range/adaptor/map.hpp
Normal file
204
include/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
|
||||
102
include/boost/range/adaptor/ref_unwrapped.hpp
Normal file
102
include/boost/range/adaptor/ref_unwrapped.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Robin Eckert 2015.
|
||||
// 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_REF_UNWRAPPED_HPP
|
||||
#define BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
|
||||
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
#include <boost/range/reference.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#include <utility>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range_detail
|
||||
{
|
||||
struct ref_unwrapped_forwarder {};
|
||||
|
||||
template<class SinglePassRange>
|
||||
struct unwrap_ref
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
range_reference<SinglePassRange>::type argument_type;
|
||||
|
||||
typedef decltype( boost::declval<argument_type>().get() ) result_type;
|
||||
|
||||
result_type operator()( argument_type &&r ) const
|
||||
{
|
||||
return r.get();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class SinglePassRange>
|
||||
class unwrap_ref_range
|
||||
: public transformed_range<unwrap_ref<SinglePassRange>,
|
||||
SinglePassRange>
|
||||
{
|
||||
typedef transformed_range<unwrap_ref<SinglePassRange>,
|
||||
SinglePassRange> base;
|
||||
public:
|
||||
typedef unwrap_ref<SinglePassRange> transform_fn_type;
|
||||
typedef SinglePassRange source_range_type;
|
||||
|
||||
unwrap_ref_range(transform_fn_type fn, source_range_type &rng)
|
||||
: base(fn, rng)
|
||||
{
|
||||
}
|
||||
|
||||
unwrap_ref_range(const base &other) : base(other) {}
|
||||
};
|
||||
|
||||
template<class SinglePassRange>
|
||||
inline unwrap_ref_range<SinglePassRange>
|
||||
operator|(SinglePassRange& r, ref_unwrapped_forwarder)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return operator|( r,
|
||||
boost::adaptors::transformed(unwrap_ref<SinglePassRange>()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using range_detail::unwrap_ref_range;
|
||||
|
||||
namespace adaptors
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const range_detail::ref_unwrapped_forwarder ref_unwrapped =
|
||||
range_detail::ref_unwrapped_forwarder();
|
||||
}
|
||||
|
||||
template<class SinglePassRange>
|
||||
inline unwrap_ref_range<SinglePassRange>
|
||||
ref_unwrap(SinglePassRange& rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return unwrap_ref_range<SinglePassRange>(
|
||||
range_detail::unwrap_ref<SinglePassRange>(), rng );
|
||||
}
|
||||
} // 'adaptors'
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
159
include/boost/range/adaptor/replaced.hpp
Normal file
159
include/boost/range/adaptor/replaced.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
// 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, class Value >
|
||||
inline replaced_range<SinglePassRange>
|
||||
operator|(SinglePassRange& r, const replace_holder<Value>& f)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return replaced_range<SinglePassRange>(r, f.val1, f.val2);
|
||||
}
|
||||
|
||||
template< class SinglePassRange, class Value >
|
||||
inline replaced_range<const SinglePassRange>
|
||||
operator|(const SinglePassRange& r, const replace_holder<Value>& 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, class Value >
|
||||
inline replaced_range<SinglePassRange>
|
||||
replace(SinglePassRange& rng, Value from, Value to)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return replaced_range<SinglePassRange>(rng, from, to);
|
||||
}
|
||||
|
||||
template< class SinglePassRange, class Value >
|
||||
inline replaced_range<const SinglePassRange>
|
||||
replace(const SinglePassRange& rng, Value from, Value to)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<const SinglePassRange>));
|
||||
|
||||
return replaced_range<const SinglePassRange>(rng, from ,to);
|
||||
}
|
||||
|
||||
} // 'adaptors'
|
||||
} // 'boost'
|
||||
|
||||
#endif // include guard
|
||||
165
include/boost/range/adaptor/replaced_if.hpp
Normal file
165
include/boost/range/adaptor/replaced_if.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
// 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, class Value >
|
||||
inline replaced_if_range<Pred, SinglePassRange>
|
||||
operator|(SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return replaced_if_range<Pred, SinglePassRange>(
|
||||
r, f.pred(), f.to());
|
||||
}
|
||||
|
||||
template< class Pred, class SinglePassRange, class Value >
|
||||
inline replaced_if_range<Pred, const SinglePassRange>
|
||||
operator|(const SinglePassRange& r, const replace_if_holder<Pred, Value>& 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, class Value >
|
||||
inline replaced_if_range<Pred, SinglePassRange>
|
||||
replace_if(SinglePassRange& rng, Pred pred, Value to)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return range_detail::replaced_if_range<Pred, SinglePassRange>(
|
||||
rng, pred, to);
|
||||
}
|
||||
|
||||
template< class Pred, class SinglePassRange, class Value >
|
||||
inline replaced_if_range<Pred, const SinglePassRange>
|
||||
replace_if(const SinglePassRange& rng, Pred pred, Value 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
include/boost/range/adaptor/reversed.hpp
Normal file
103
include/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
|
||||
97
include/boost/range/adaptor/sliced.hpp
Normal file
97
include/boost/range/adaptor/sliced.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_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>
|
||||
#include <boost/next_prior.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
|
||||
698
include/boost/range/adaptor/strided.hpp
Normal file
698
include/boost/range/adaptor/strided.hpp
Normal file
@@ -0,0 +1,698 @@
|
||||
// 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 <boost/iterator/enable_if_convertible.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 iterators::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 iterators::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 iterators::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 iterators::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 iterators::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 iterators::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 iterators::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 iterators::pure_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
include/boost/range/adaptor/tokenized.hpp
Normal file
137
include/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
include/boost/range/adaptor/transformed.hpp
Normal file
137
include/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
include/boost/range/adaptor/type_erased.hpp
Normal file
196
include/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
include/boost/range/adaptor/uniqued.hpp
Normal file
97
include/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
|
||||
Reference in New Issue
Block a user