Squashed 'third_party/boostorg/range/' content from commit 4cfd4d8
Change-Id: I641c49f21039952b16f888223a952503e43a28a9
git-subtree-dir: third_party/boostorg/range
git-subtree-split: 4cfd4d8287ca949d7f29256adf3e796a0d1775ec
diff --git a/include/boost/range/adaptor/adjacent_filtered.hpp b/include/boost/range/adaptor/adjacent_filtered.hpp
new file mode 100644
index 0000000..405fe7b
--- /dev/null
+++ b/include/boost/range/adaptor/adjacent_filtered.hpp
@@ -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
diff --git a/include/boost/range/adaptor/argument_fwd.hpp b/include/boost/range/adaptor/argument_fwd.hpp
new file mode 100644
index 0000000..fbfd40c
--- /dev/null
+++ b/include/boost/range/adaptor/argument_fwd.hpp
@@ -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
diff --git a/include/boost/range/adaptor/copied.hpp b/include/boost/range/adaptor/copied.hpp
new file mode 100644
index 0000000..f7dfbcd
--- /dev/null
+++ b/include/boost/range/adaptor/copied.hpp
@@ -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
diff --git a/include/boost/range/adaptor/define_adaptor.hpp b/include/boost/range/adaptor/define_adaptor.hpp
new file mode 100644
index 0000000..b228df3
--- /dev/null
+++ b/include/boost/range/adaptor/define_adaptor.hpp
@@ -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
diff --git a/include/boost/range/adaptor/filtered.hpp b/include/boost/range/adaptor/filtered.hpp
new file mode 100644
index 0000000..1fb778e
--- /dev/null
+++ b/include/boost/range/adaptor/filtered.hpp
@@ -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
diff --git a/include/boost/range/adaptor/formatted.hpp b/include/boost/range/adaptor/formatted.hpp
new file mode 100644
index 0000000..f31f1bc
--- /dev/null
+++ b/include/boost/range/adaptor/formatted.hpp
@@ -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
diff --git a/include/boost/range/adaptor/indexed.hpp b/include/boost/range/adaptor/indexed.hpp
new file mode 100644
index 0000000..a426bd6
--- /dev/null
+++ b/include/boost/range/adaptor/indexed.hpp
@@ -0,0 +1,370 @@
+// Copyright 2014 Neil Groves
+//
+// Copyright (c) 2010 Ilya Murav'jov
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Credits:
+// My (Neil's) first indexed adaptor was hindered by having the underlying
+// iterator return the same reference as the wrapped iterator. This meant that
+// to obtain the index one had to get to the index_iterator and call the
+// index() function on it. Ilya politely pointed out that this was useless in
+// a number of scenarios since one naturally hides the use of iterators in
+// good range-based code. Ilya provided a new interface (which has remained)
+// and a first implementation. Much of this original implementation has
+// been simplified and now supports more compilers and platforms.
+//
+#ifndef BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/traversal.hpp>
+#include <boost/range/size.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+namespace boost
+{
+ namespace adaptors
+ {
+
+struct indexed
+{
+ explicit indexed(std::ptrdiff_t x = 0)
+ : val(x)
+ {
+ }
+ std::ptrdiff_t val;
+};
+
+ } // namespace adaptors
+
+ namespace range
+ {
+
+// Why yet another "pair" class:
+// - std::pair can't store references
+// - no need for typing for index type (default to "std::ptrdiff_t"); this is
+// useful in BOOST_FOREACH() expressions that have pitfalls with commas
+// ( see http://www.boost.org/doc/libs/1_44_0/doc/html/foreach/pitfalls.html )
+// - meaningful access functions index(), value()
+template<class T, class Indexable = std::ptrdiff_t>
+class index_value
+ : public tuple<Indexable, T>
+{
+ typedef tuple<Indexable, T> base_t;
+
+ template<int N>
+ struct iv_types
+ {
+ typedef typename tuples::element<N, base_t>::type n_type;
+
+ typedef typename tuples::access_traits<n_type>::non_const_type non_const_type;
+ typedef typename tuples::access_traits<n_type>::const_type const_type;
+ };
+
+public:
+ typedef typename iv_types<0>::non_const_type index_type;
+ typedef typename iv_types<0>::const_type const_index_type;
+ typedef typename iv_types<1>::non_const_type value_type;
+ typedef typename iv_types<1>::const_type const_value_type;
+
+ index_value()
+ {
+ }
+
+ index_value(typename tuples::access_traits<Indexable>::parameter_type t0,
+ typename tuples::access_traits<T>::parameter_type t1)
+ : base_t(t0, t1)
+ {
+ }
+
+ // member functions index(), value() (non-const and const)
+ index_type index()
+ {
+ return boost::tuples::get<0>(*this);
+ }
+
+ const_index_type index() const
+ {
+ return boost::tuples::get<0>(*this);
+ }
+
+ value_type value()
+ {
+ return boost::tuples::get<1>(*this);
+ }
+
+ const_value_type value() const
+ {
+ return boost::tuples::get<1>(*this);
+ }
+};
+
+ } // namespace range
+
+namespace range_detail
+{
+
+template<typename Iter>
+struct indexed_iterator_value_type
+{
+ typedef ::boost::range::index_value<
+ typename iterator_reference<Iter>::type,
+ typename iterator_difference<Iter>::type
+ > type;
+};
+
+// Meta-function to get the traversal for the range and therefore iterator
+// returned by the indexed adaptor for a specified iterator type.
+//
+// Random access -> Random access
+// Bidirectional -> Forward
+// Forward -> Forward
+// SinglePass -> SinglePass
+//
+// The rationale for demoting a Bidirectional input to Forward is that the end
+// iterator cannot cheaply have an index computed for it. Therefore I chose to
+// demote to forward traversal. I can maintain the ability to traverse randomly
+// when the input is Random Access since the index for the end iterator is cheap
+// to compute.
+template<typename Iter>
+struct indexed_traversal
+{
+private:
+ typedef typename iterator_traversal<Iter>::type wrapped_traversal;
+
+public:
+
+ typedef typename mpl::if_<
+ is_convertible<wrapped_traversal, random_access_traversal_tag>,
+ random_access_traversal_tag,
+ typename mpl::if_<
+ is_convertible<wrapped_traversal, bidirectional_traversal_tag>,
+ forward_traversal_tag,
+ wrapped_traversal
+ >::type
+ >::type type;
+};
+
+template<typename Iter>
+class indexed_iterator
+ : public iterator_facade<
+ indexed_iterator<Iter>,
+ typename indexed_iterator_value_type<Iter>::type,
+ typename indexed_traversal<Iter>::type,
+ typename indexed_iterator_value_type<Iter>::type,
+ typename iterator_difference<Iter>::type
+ >
+{
+public:
+ typedef Iter wrapped;
+
+private:
+ typedef iterator_facade<
+ indexed_iterator<wrapped>,
+ typename indexed_iterator_value_type<wrapped>::type,
+ typename indexed_traversal<wrapped>::type,
+ typename indexed_iterator_value_type<wrapped>::type,
+ typename iterator_difference<wrapped>::type
+ > base_t;
+
+public:
+ typedef typename base_t::difference_type difference_type;
+ typedef typename base_t::reference reference;
+ typedef typename base_t::difference_type index_type;
+
+ indexed_iterator()
+ : m_it()
+ , m_index()
+ {
+ }
+
+ template<typename OtherWrapped>
+ indexed_iterator(
+ const indexed_iterator<OtherWrapped>& other,
+ typename enable_if<is_convertible<OtherWrapped, wrapped> >::type* = 0
+ )
+ : m_it(other.get())
+ , m_index(other.get_index())
+ {
+ }
+
+ explicit indexed_iterator(wrapped it, index_type index)
+ : m_it(it)
+ , m_index(index)
+ {
+ }
+
+ wrapped get() const
+ {
+ return m_it;
+ }
+
+ index_type get_index() const
+ {
+ return m_index;
+ }
+
+ private:
+ friend class boost::iterator_core_access;
+
+ reference dereference() const
+ {
+ return reference(m_index, *m_it);
+ }
+
+ bool equal(const indexed_iterator& other) const
+ {
+ return m_it == other.m_it;
+ }
+
+ void increment()
+ {
+ ++m_index;
+ ++m_it;
+ }
+
+ void decrement()
+ {
+ BOOST_ASSERT_MSG(m_index > 0, "indexed Iterator out of bounds");
+ --m_index;
+ --m_it;
+ }
+
+ void advance(index_type n)
+ {
+ m_index += n;
+ BOOST_ASSERT_MSG(m_index >= 0, "indexed Iterator out of bounds");
+ m_it += n;
+ }
+
+ difference_type distance_to(const indexed_iterator& other) const
+ {
+ return other.m_it - m_it;
+ }
+
+ wrapped m_it;
+ index_type m_index;
+};
+
+template<typename SinglePassRange>
+struct indexed_range
+ : iterator_range<
+ indexed_iterator<
+ typename range_iterator<SinglePassRange>::type
+ >
+ >
+{
+ typedef iterator_range<
+ indexed_iterator<
+ typename range_iterator<SinglePassRange>::type
+ >
+ > base_t;
+
+ BOOST_RANGE_CONCEPT_ASSERT((
+ boost::SinglePassRangeConcept<SinglePassRange>));
+public:
+ typedef indexed_iterator<
+ typename range_iterator<SinglePassRange>::type
+ > iterator;
+
+ // Constructor for non-random access iterators.
+ // This sets the end iterator index to i despite this being incorrect it
+ // is never observable since bidirectional iterators are demoted to
+ // forward iterators.
+ indexed_range(
+ typename base_t::difference_type i,
+ SinglePassRange& r,
+ single_pass_traversal_tag
+ )
+ : base_t(iterator(boost::begin(r), i),
+ iterator(boost::end(r), i))
+ {
+ }
+
+ indexed_range(
+ typename base_t::difference_type i,
+ SinglePassRange& r,
+ random_access_traversal_tag
+ )
+ : base_t(iterator(boost::begin(r), i),
+ iterator(boost::end(r), i + boost::size(r)))
+ {
+ }
+};
+
+ } // namespace range_detail
+
+ using range_detail::indexed_range;
+
+ namespace adaptors
+ {
+
+template<class SinglePassRange>
+inline indexed_range<SinglePassRange>
+operator|(SinglePassRange& r, indexed e)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((
+ boost::SinglePassRangeConcept<SinglePassRange>
+ ));
+ return indexed_range<SinglePassRange>(
+ e.val, r,
+ typename range_traversal<SinglePassRange>::type());
+}
+
+template<class SinglePassRange>
+inline indexed_range<const SinglePassRange>
+operator|(const SinglePassRange& r, indexed e)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((
+ boost::SinglePassRangeConcept<const SinglePassRange>
+ ));
+ return indexed_range<const SinglePassRange>(
+ e.val, r,
+ typename range_traversal<const SinglePassRange>::type());
+}
+
+template<class SinglePassRange>
+inline indexed_range<SinglePassRange>
+index(
+ SinglePassRange& rng,
+ typename range_difference<SinglePassRange>::type index_value = 0)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((
+ boost::SinglePassRangeConcept<SinglePassRange>
+ ));
+ return indexed_range<SinglePassRange>(
+ index_value, rng,
+ typename range_traversal<SinglePassRange>::type());
+}
+
+template<class SinglePassRange>
+inline indexed_range<const SinglePassRange>
+index(
+ const SinglePassRange& rng,
+ typename range_difference<const SinglePassRange>::type index_value = 0)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((
+ boost::SinglePassRangeConcept<SinglePassRange>
+ ));
+ return indexed_range<const SinglePassRange>(
+ index_value, rng,
+ typename range_traversal<const SinglePassRange>::type());
+}
+
+ } // namespace adaptors
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/adaptor/indirected.hpp b/include/boost/range/adaptor/indirected.hpp
new file mode 100644
index 0000000..e741f17
--- /dev/null
+++ b/include/boost/range/adaptor/indirected.hpp
@@ -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
diff --git a/include/boost/range/adaptor/map.hpp b/include/boost/range/adaptor/map.hpp
new file mode 100644
index 0000000..2d922ea
--- /dev/null
+++ b/include/boost/range/adaptor/map.hpp
@@ -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
diff --git a/include/boost/range/adaptor/ref_unwrapped.hpp b/include/boost/range/adaptor/ref_unwrapped.hpp
new file mode 100644
index 0000000..71af483
--- /dev/null
+++ b/include/boost/range/adaptor/ref_unwrapped.hpp
@@ -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 <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;
+
+ using result_type = decltype(std::declval<argument_type>().get() );
+
+ result_type operator()( argument_type &&r ) const
+ {
+ return r.get();
+ }
+ };
+
+
+ template<class SinglePassRange>
+ class unwrap_ref_range
+ : public transformed_range<unwrap_ref<SinglePassRange>,
+ SinglePassRange>
+ {
+ using base = transformed_range<unwrap_ref<SinglePassRange>,
+ SinglePassRange>;
+ public:
+ using transform_fn_type = unwrap_ref<SinglePassRange>;
+ using source_range_type = SinglePassRange;
+
+ 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
diff --git a/include/boost/range/adaptor/replaced.hpp b/include/boost/range/adaptor/replaced.hpp
new file mode 100644
index 0000000..42eb52a
--- /dev/null
+++ b/include/boost/range/adaptor/replaced.hpp
@@ -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
diff --git a/include/boost/range/adaptor/replaced_if.hpp b/include/boost/range/adaptor/replaced_if.hpp
new file mode 100644
index 0000000..83d3ec8
--- /dev/null
+++ b/include/boost/range/adaptor/replaced_if.hpp
@@ -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
diff --git a/include/boost/range/adaptor/reversed.hpp b/include/boost/range/adaptor/reversed.hpp
new file mode 100644
index 0000000..944fbff
--- /dev/null
+++ b/include/boost/range/adaptor/reversed.hpp
@@ -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
diff --git a/include/boost/range/adaptor/sliced.hpp b/include/boost/range/adaptor/sliced.hpp
new file mode 100644
index 0000000..f8d9612
--- /dev/null
+++ b/include/boost/range/adaptor/sliced.hpp
@@ -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
diff --git a/include/boost/range/adaptor/strided.hpp b/include/boost/range/adaptor/strided.hpp
new file mode 100644
index 0000000..560b820
--- /dev/null
+++ b/include/boost/range/adaptor/strided.hpp
@@ -0,0 +1,697 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <iterator>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // strided_iterator for wrapping a forward traversal iterator
+ template<class BaseIterator, class Category>
+ class strided_iterator
+ : public iterator_facade<
+ strided_iterator<BaseIterator, Category>
+ , typename iterator_value<BaseIterator>::type
+ , forward_traversal_tag
+ , typename iterator_reference<BaseIterator>::type
+ , typename iterator_difference<BaseIterator>::type
+ >
+ {
+ friend class ::boost::iterator_core_access;
+
+ typedef iterator_facade<
+ strided_iterator<BaseIterator, Category>
+ , typename iterator_value<BaseIterator>::type
+ , forward_traversal_tag
+ , typename iterator_reference<BaseIterator>::type
+ , typename iterator_difference<BaseIterator>::type
+ > super_t;
+
+ public:
+ typedef typename super_t::difference_type difference_type;
+ typedef typename super_t::reference reference;
+ typedef BaseIterator base_iterator;
+ typedef std::forward_iterator_tag iterator_category;
+
+ strided_iterator()
+ : m_it()
+ , m_last()
+ , m_stride()
+ {
+ }
+
+ strided_iterator(base_iterator it,
+ base_iterator last,
+ difference_type stride)
+ : m_it(it)
+ , m_last(last)
+ , m_stride(stride)
+ {
+ }
+
+ template<class OtherIterator>
+ strided_iterator(
+ const strided_iterator<OtherIterator, Category>& other,
+ typename enable_if_convertible<
+ OtherIterator,
+ base_iterator
+ >::type* = 0
+ )
+ : m_it(other.base())
+ , m_last(other.base_end())
+ , m_stride(other.get_stride())
+ {
+ }
+
+ base_iterator base() const
+ {
+ return m_it;
+ }
+
+ base_iterator base_end() const
+ {
+ return m_last;
+ }
+
+ difference_type get_stride() const
+ {
+ return m_stride;
+ }
+
+ private:
+ void increment()
+ {
+ for (difference_type i = 0;
+ (m_it != m_last) && (i < m_stride); ++i)
+ {
+ ++m_it;
+ }
+ }
+
+ reference dereference() const
+ {
+ return *m_it;
+ }
+
+ template<class OtherIterator>
+ bool equal(
+ const strided_iterator<OtherIterator, Category>& other,
+ typename enable_if_convertible<
+ OtherIterator,
+ base_iterator
+ >::type* = 0) const
+ {
+ return m_it == other.m_it;
+ }
+
+ base_iterator m_it;
+ base_iterator m_last;
+ difference_type m_stride;
+ };
+
+ // strided_iterator for wrapping a bidirectional iterator
+ template<class BaseIterator>
+ class strided_iterator<BaseIterator, bidirectional_traversal_tag>
+ : public iterator_facade<
+ strided_iterator<BaseIterator, bidirectional_traversal_tag>
+ , typename iterator_value<BaseIterator>::type
+ , bidirectional_traversal_tag
+ , typename iterator_reference<BaseIterator>::type
+ , typename iterator_difference<BaseIterator>::type
+ >
+ {
+ friend class ::boost::iterator_core_access;
+
+ typedef iterator_facade<
+ strided_iterator<BaseIterator, bidirectional_traversal_tag>
+ , typename iterator_value<BaseIterator>::type
+ , bidirectional_traversal_tag
+ , typename iterator_reference<BaseIterator>::type
+ , typename iterator_difference<BaseIterator>::type
+ > super_t;
+ public:
+ typedef typename super_t::difference_type difference_type;
+ typedef typename super_t::reference reference;
+ typedef BaseIterator base_iterator;
+ typedef typename boost::make_unsigned<difference_type>::type
+ size_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ strided_iterator()
+ : m_it()
+ , m_offset()
+ , m_index()
+ , m_stride()
+ {
+ }
+
+ strided_iterator(base_iterator it,
+ size_type index,
+ difference_type stride)
+ : m_it(it)
+ , m_offset()
+ , m_index(index)
+ , m_stride(stride)
+ {
+ if (stride && ((m_index % stride) != 0))
+ m_index += (stride - (m_index % stride));
+ }
+
+ template<class OtherIterator>
+ strided_iterator(
+ const strided_iterator<
+ OtherIterator,
+ bidirectional_traversal_tag
+ >& other,
+ typename enable_if_convertible<
+ OtherIterator,
+ base_iterator
+ >::type* = 0
+ )
+ : m_it(other.base())
+ , m_offset(other.get_offset())
+ , m_index(other.get_index())
+ , m_stride(other.get_stride())
+ {
+ }
+
+ base_iterator base() const
+ {
+ return m_it;
+ }
+
+ difference_type get_offset() const
+ {
+ return m_offset;
+ }
+
+ size_type get_index() const
+ {
+ return m_index;
+ }
+
+ difference_type get_stride() const
+ {
+ return m_stride;
+ }
+
+ private:
+ void increment()
+ {
+ m_offset += m_stride;
+ }
+
+ void decrement()
+ {
+ m_offset -= m_stride;
+ }
+
+ reference dereference() const
+ {
+ update();
+ return *m_it;
+ }
+
+ void update() const
+ {
+ std::advance(m_it, m_offset);
+ m_index += m_offset;
+ m_offset = 0;
+ }
+
+ template<class OtherIterator>
+ bool equal(
+ const strided_iterator<
+ OtherIterator,
+ bidirectional_traversal_tag
+ >& other,
+ typename enable_if_convertible<
+ OtherIterator,
+ base_iterator
+ >::type* = 0) const
+ {
+ return (m_index + m_offset) ==
+ (other.get_index() + other.get_offset());
+ }
+
+ mutable base_iterator m_it;
+ mutable difference_type m_offset;
+ mutable size_type m_index;
+ difference_type m_stride;
+ };
+
+ // strided_iterator implementation for wrapping a random access iterator
+ template<class BaseIterator>
+ class strided_iterator<BaseIterator, random_access_traversal_tag>
+ : public iterator_facade<
+ strided_iterator<BaseIterator, random_access_traversal_tag>
+ , typename iterator_value<BaseIterator>::type
+ , random_access_traversal_tag
+ , typename iterator_reference<BaseIterator>::type
+ , typename iterator_difference<BaseIterator>::type
+ >
+ {
+ friend class ::boost::iterator_core_access;
+
+ typedef iterator_facade<
+ strided_iterator<BaseIterator, random_access_traversal_tag>
+ , typename iterator_value<BaseIterator>::type
+ , random_access_traversal_tag
+ , typename iterator_reference<BaseIterator>::type
+ , typename iterator_difference<BaseIterator>::type
+ > super_t;
+ public:
+ typedef typename super_t::difference_type difference_type;
+ typedef typename super_t::reference reference;
+ typedef BaseIterator base_iterator;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ strided_iterator()
+ : m_it()
+ , m_first()
+ , m_index(0)
+ , m_stride()
+ {
+ }
+
+ strided_iterator(
+ base_iterator first,
+ base_iterator it,
+ difference_type stride
+ )
+ : m_it(it)
+ , m_first(first)
+ , m_index(stride ? (it - first) : difference_type())
+ , m_stride(stride)
+ {
+ if (stride && ((m_index % stride) != 0))
+ m_index += (stride - (m_index % stride));
+ }
+
+ template<class OtherIterator>
+ strided_iterator(
+ const strided_iterator<
+ OtherIterator,
+ random_access_traversal_tag
+ >& other,
+ typename enable_if_convertible<
+ OtherIterator,
+ base_iterator
+ >::type* = 0
+ )
+ : m_it(other.base())
+ , m_first(other.base_begin())
+ , m_index(other.get_index())
+ , m_stride(other.get_stride())
+ {
+ }
+
+ base_iterator base_begin() const
+ {
+ return m_first;
+ }
+
+ base_iterator base() const
+ {
+ return m_it;
+ }
+
+ difference_type get_stride() const
+ {
+ return m_stride;
+ }
+
+ difference_type get_index() const
+ {
+ return m_index;
+ }
+
+ private:
+ void increment()
+ {
+ m_index += m_stride;
+ }
+
+ void decrement()
+ {
+ m_index -= m_stride;
+ }
+
+ void advance(difference_type offset)
+ {
+ m_index += (m_stride * offset);
+ }
+
+ // Implementation detail: only update the actual underlying iterator
+ // at the point of dereference. This is done so that the increment
+ // and decrement can overshoot the valid sequence as is required
+ // by striding. Since we can do all comparisons just with the index
+ // simply, and all dereferences must be within the valid range.
+ void update() const
+ {
+ m_it = m_first + m_index;
+ }
+
+ template<class OtherIterator>
+ difference_type distance_to(
+ const strided_iterator<
+ OtherIterator,
+ random_access_traversal_tag
+ >& other,
+ typename enable_if_convertible<
+ OtherIterator, base_iterator>::type* = 0) const
+ {
+ BOOST_ASSERT((other.m_index - m_index) % m_stride == difference_type());
+ return (other.m_index - m_index) / m_stride;
+ }
+
+ template<class OtherIterator>
+ bool equal(
+ const strided_iterator<
+ OtherIterator,
+ random_access_traversal_tag
+ >& other,
+ typename enable_if_convertible<
+ OtherIterator, base_iterator>::type* = 0) const
+ {
+ return m_index == other.m_index;
+ }
+
+ reference dereference() const
+ {
+ update();
+ return *m_it;
+ }
+
+ private:
+ mutable base_iterator m_it;
+ base_iterator m_first;
+ difference_type m_index;
+ difference_type m_stride;
+ };
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<Rng>::type,
+ forward_traversal_tag
+ >
+ make_begin_strided_iterator(
+ Rng& rng,
+ Difference stride,
+ forward_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<Rng>::type,
+ forward_traversal_tag
+ >(boost::begin(rng), boost::end(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<const Rng>::type,
+ forward_traversal_tag
+ >
+ make_begin_strided_iterator(
+ const Rng& rng,
+ Difference stride,
+ forward_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<const Rng>::type,
+ forward_traversal_tag
+ >(boost::begin(rng), boost::end(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<Rng>::type,
+ forward_traversal_tag
+ >
+ make_end_strided_iterator(
+ Rng& rng,
+ Difference stride,
+ forward_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<Rng>::type,
+ forward_traversal_tag
+ >(boost::end(rng), boost::end(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<const Rng>::type,
+ forward_traversal_tag
+ >
+ make_end_strided_iterator(
+ const Rng& rng,
+ Difference stride,
+ forward_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<const Rng>::type,
+ forward_traversal_tag
+ >(boost::end(rng), boost::end(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<Rng>::type,
+ bidirectional_traversal_tag
+ >
+ make_begin_strided_iterator(
+ Rng& rng,
+ Difference stride,
+ bidirectional_traversal_tag)
+ {
+ typedef typename range_difference<Rng>::type difference_type;
+
+ return strided_iterator<
+ typename range_iterator<Rng>::type,
+ bidirectional_traversal_tag
+ >(boost::begin(rng), difference_type(), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<const Rng>::type,
+ bidirectional_traversal_tag
+ >
+ make_begin_strided_iterator(
+ const Rng& rng,
+ Difference stride,
+ bidirectional_traversal_tag)
+ {
+ typedef typename range_difference<const Rng>::type difference_type;
+
+ return strided_iterator<
+ typename range_iterator<const Rng>::type,
+ bidirectional_traversal_tag
+ >(boost::begin(rng), difference_type(), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<Rng>::type,
+ bidirectional_traversal_tag
+ >
+ make_end_strided_iterator(
+ Rng& rng,
+ Difference stride,
+ bidirectional_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<Rng>::type,
+ bidirectional_traversal_tag
+ >(boost::end(rng), boost::size(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<const Rng>::type,
+ bidirectional_traversal_tag
+ >
+ make_end_strided_iterator(
+ const Rng& rng,
+ Difference stride,
+ bidirectional_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<const Rng>::type,
+ bidirectional_traversal_tag
+ >(boost::end(rng), boost::size(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<Rng>::type,
+ random_access_traversal_tag
+ >
+ make_begin_strided_iterator(
+ Rng& rng,
+ Difference stride,
+ random_access_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<Rng>::type,
+ random_access_traversal_tag
+ >(boost::begin(rng), boost::begin(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<const Rng>::type,
+ random_access_traversal_tag
+ >
+ make_begin_strided_iterator(
+ const Rng& rng,
+ Difference stride,
+ random_access_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<const Rng>::type,
+ random_access_traversal_tag
+ >(boost::begin(rng), boost::begin(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<Rng>::type,
+ random_access_traversal_tag
+ >
+ make_end_strided_iterator(
+ Rng& rng,
+ Difference stride,
+ random_access_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<Rng>::type,
+ random_access_traversal_tag
+ >(boost::begin(rng), boost::end(rng), stride);
+ }
+
+ template<class Rng, class Difference> inline
+ strided_iterator<
+ typename range_iterator<const Rng>::type,
+ random_access_traversal_tag
+ >
+ make_end_strided_iterator(
+ const Rng& rng,
+ Difference stride,
+ random_access_traversal_tag)
+ {
+ return strided_iterator<
+ typename range_iterator<const Rng>::type,
+ random_access_traversal_tag
+ >(boost::begin(rng), boost::end(rng), stride);
+ }
+
+ template<
+ class Rng,
+ class Category =
+ typename 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
diff --git a/include/boost/range/adaptor/tokenized.hpp b/include/boost/range/adaptor/tokenized.hpp
new file mode 100644
index 0000000..f0aa12e
--- /dev/null
+++ b/include/boost/range/adaptor/tokenized.hpp
@@ -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
diff --git a/include/boost/range/adaptor/transformed.hpp b/include/boost/range/adaptor/transformed.hpp
new file mode 100644
index 0000000..428ff4b
--- /dev/null
+++ b/include/boost/range/adaptor/transformed.hpp
@@ -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
diff --git a/include/boost/range/adaptor/type_erased.hpp b/include/boost/range/adaptor/type_erased.hpp
new file mode 100644
index 0000000..ba5b159
--- /dev/null
+++ b/include/boost/range/adaptor/type_erased.hpp
@@ -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
diff --git a/include/boost/range/adaptor/uniqued.hpp b/include/boost/range/adaptor/uniqued.hpp
new file mode 100644
index 0000000..29101d3
--- /dev/null
+++ b/include/boost/range/adaptor/uniqued.hpp
@@ -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