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/algorithm/adjacent_find.hpp b/include/boost/range/algorithm/adjacent_find.hpp
new file mode 100644
index 0000000..1b88dae
--- /dev/null
+++ b/include/boost/range/algorithm/adjacent_find.hpp
@@ -0,0 +1,125 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function adjacent_find
+///
+/// range-based version of the adjacent_find std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< typename ForwardRange >
+inline typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange & rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng));
+}
+
+/// \overload
+template< typename ForwardRange >
+inline typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng));
+}
+
+/// \overload
+template< typename ForwardRange, typename BinaryPredicate >
+inline typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange & rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ typename range_value<ForwardRange>::type,
+ typename range_value<ForwardRange>::type>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
+}
+
+/// \overload
+template< typename ForwardRange, typename BinaryPredicate >
+inline typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ typename range_value<const ForwardRange>::type,
+ typename range_value<const ForwardRange>::type>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, typename ForwardRange >
+inline typename range_return<ForwardRange,re>::type
+adjacent_find(ForwardRange & rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange >
+inline typename range_return<const ForwardRange,re>::type
+adjacent_find(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<const ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
+inline typename range_return<ForwardRange,re>::type
+adjacent_find(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ typename range_value<ForwardRange>::type,
+ typename range_value<ForwardRange>::type>));
+ return range_return<ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
+inline typename range_return<const ForwardRange,re>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<const ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
+ rng);
+}
+
+ } // namespace range
+ using range::adjacent_find;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/binary_search.hpp b/include/boost/range/algorithm/binary_search.hpp
new file mode 100644
index 0000000..bb64ec8
--- /dev/null
+++ b/include/boost/range/algorithm/binary_search.hpp
@@ -0,0 +1,49 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function binary_search
+///
+/// range-based version of the binary_search std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange, class Value>
+inline bool binary_search(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::binary_search(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class BinaryPredicate>
+inline bool binary_search(const ForwardRange& rng, const Value& val,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::binary_search(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+ } // namespace range
+ using range::binary_search;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/copy.hpp b/include/boost/range/algorithm/copy.hpp
new file mode 100644
index 0000000..f15b31f
--- /dev/null
+++ b/include/boost/range/algorithm/copy.hpp
@@ -0,0 +1,41 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function copy
+///
+/// range-based version of the copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+template< class SinglePassRange, class OutputIterator >
+inline OutputIterator copy(const SinglePassRange& rng, OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::copy(boost::begin(rng),boost::end(rng),out);
+}
+
+ } // namespace range
+ using range::copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/copy_backward.hpp b/include/boost/range/algorithm/copy_backward.hpp
new file mode 100644
index 0000000..c95c6f1
--- /dev/null
+++ b/include/boost/range/algorithm/copy_backward.hpp
@@ -0,0 +1,43 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function copy_backward
+///
+/// range-based version of the copy_backwards std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre BidirectionalTraversalWriteableIterator is a model of the BidirectionalIteratorConcept
+/// \pre BidirectionalTraversalWriteableIterator is a model of the WriteableIteratorConcept
+template< class BidirectionalRange, class BidirectionalTraversalWriteableIterator >
+inline BidirectionalTraversalWriteableIterator
+copy_backward(const BidirectionalRange& rng,
+ BidirectionalTraversalWriteableIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::copy_backward(boost::begin(rng), boost::end(rng), out);
+}
+
+ } // namespace range
+ using range::copy_backward;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/count.hpp b/include/boost/range/algorithm/count.hpp
new file mode 100644
index 0000000..8316ce0
--- /dev/null
+++ b/include/boost/range/algorithm/count.hpp
@@ -0,0 +1,50 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function count
+///
+/// range-based version of the count std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
+count(SinglePassRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::count(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange const>::type
+count(const SinglePassRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::count(boost::begin(rng), boost::end(rng), val);
+}
+
+ } // namespace range
+ using range::count;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/count_if.hpp b/include/boost/range/algorithm/count_if.hpp
new file mode 100644
index 0000000..ae17b0e
--- /dev/null
+++ b/include/boost/range/algorithm/count_if.hpp
@@ -0,0 +1,51 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function count_if
+///
+/// range-based version of the count_if std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<SinglePassRange>::type
+count_if(SinglePassRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::count_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<const SinglePassRange>::type
+count_if(const SinglePassRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::count_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+ } // namespace range
+ using range::count_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/equal.hpp b/include/boost/range/algorithm/equal.hpp
new file mode 100644
index 0000000..2b44f3b
--- /dev/null
+++ b/include/boost/range/algorithm/equal.hpp
@@ -0,0 +1,200 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <iterator>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // An implementation of equality comparison that is optimized for iterator
+ // traversal categories less than RandomAccessTraversal.
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class IteratorCategoryTag1,
+ class IteratorCategoryTag2 >
+ inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ IteratorCategoryTag1,
+ IteratorCategoryTag2 )
+ {
+ for (;;)
+ {
+ // If we have reached the end of the left range then this is
+ // the end of the loop. They are equal if and only if we have
+ // simultaneously reached the end of the right range.
+ if (first1 == last1)
+ return first2 == last2;
+
+ // If we have reached the end of the right range at this line
+ // it indicates that the right range is shorter than the left
+ // and hence the result is false.
+ if (first2 == last2)
+ return false;
+
+ // continue looping if and only if the values are equal
+ if (*first1 != *first2)
+ break;
+
+ ++first1;
+ ++first2;
+ }
+
+ // Reaching this line in the algorithm indicates that a value
+ // inequality has been detected.
+ return false;
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class IteratorCategoryTag1,
+ class IteratorCategoryTag2,
+ class BinaryPredicate >
+ inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ BinaryPredicate pred,
+ IteratorCategoryTag1,
+ IteratorCategoryTag2 )
+ {
+ for (;;)
+ {
+ // If we have reached the end of the left range then this is
+ // the end of the loop. They are equal if and only if we have
+ // simultaneously reached the end of the right range.
+ if (first1 == last1)
+ return first2 == last2;
+
+ // If we have reached the end of the right range at this line
+ // it indicates that the right range is shorter than the left
+ // and hence the result is false.
+ if (first2 == last2)
+ return false;
+
+ // continue looping if and only if the values are equal
+ if (!pred(*first1, *first2))
+ break;
+
+ ++first1;
+ ++first2;
+ }
+
+ // Reaching this line in the algorithm indicates that a value
+ // inequality has been detected.
+ return false;
+ }
+
+ // An implementation of equality comparison that is optimized for
+ // random access iterators.
+ template< class RandomAccessTraversalReadableIterator1,
+ class RandomAccessTraversalReadableIterator2 >
+ inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
+ RandomAccessTraversalReadableIterator1 last1,
+ RandomAccessTraversalReadableIterator2 first2,
+ RandomAccessTraversalReadableIterator2 last2,
+ std::random_access_iterator_tag,
+ std::random_access_iterator_tag )
+ {
+ return ((last1 - first1) == (last2 - first2))
+ && std::equal(first1, last1, first2);
+ }
+
+ template< class RandomAccessTraversalReadableIterator1,
+ class RandomAccessTraversalReadableIterator2,
+ class BinaryPredicate >
+ inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
+ RandomAccessTraversalReadableIterator1 last1,
+ RandomAccessTraversalReadableIterator2 first2,
+ RandomAccessTraversalReadableIterator2 last2,
+ BinaryPredicate pred,
+ std::random_access_iterator_tag,
+ std::random_access_iterator_tag )
+ {
+ return ((last1 - first1) == (last2 - first2))
+ && std::equal(first1, last1, first2, pred);
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2 >
+ inline bool equal( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2 )
+ {
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
+
+ return equal_impl(first1, last1, first2, last2, tag1, tag2);
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class BinaryPredicate >
+ inline bool equal( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ BinaryPredicate pred )
+ {
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
+
+ return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
+ }
+
+ } // namespace range_detail
+
+ namespace range
+ {
+
+ /// \brief template function equal
+ ///
+ /// range-based version of the equal std algorithm
+ ///
+ /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+ /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+ /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+ template< class SinglePassRange1, class SinglePassRange2 >
+ inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::equal(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2) );
+ }
+
+ /// \overload
+ template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+ inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
+ BinaryPredicate pred )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::equal(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2),
+ pred);
+ }
+
+ } // namespace range
+ using ::boost::range::equal;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/equal_range.hpp b/include/boost/range/algorithm/equal_range.hpp
new file mode 100644
index 0000000..4aa4a54
--- /dev/null
+++ b/include/boost/range/algorithm/equal_range.hpp
@@ -0,0 +1,80 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function equal_range
+///
+/// range-based version of the equal_range std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre SortPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange, class Value>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+ >
+equal_range(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+ >
+equal_range(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class SortPredicate>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+ >
+equal_range(ForwardRange& rng, const Value& val, SortPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class SortPredicate>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+ >
+equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+ } // namespace range
+ using range::equal_range;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/fill.hpp b/include/boost/range/algorithm/fill.hpp
new file mode 100644
index 0000000..95231a8
--- /dev/null
+++ b/include/boost/range/algorithm/fill.hpp
@@ -0,0 +1,49 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function fill
+///
+/// range-based version of the fill std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline ForwardRange& fill(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::fill(boost::begin(rng), boost::end(rng), val);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline const ForwardRange& fill(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::fill(boost::begin(rng), boost::end(rng), val);
+ return rng;
+}
+
+ } // namespace range
+ using range::fill;
+}
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/fill_n.hpp b/include/boost/range/algorithm/fill_n.hpp
new file mode 100644
index 0000000..02a0c2a
--- /dev/null
+++ b/include/boost/range/algorithm/fill_n.hpp
@@ -0,0 +1,53 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function fill_n
+///
+/// range-based version of the fill_n std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre n <= std::distance(boost::begin(rng), boost::end(rng))
+template< class ForwardRange, class Size, class Value >
+inline ForwardRange& fill_n(ForwardRange& rng, Size n, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
+ std::fill_n(boost::begin(rng), n, val);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Size, class Value >
+inline const ForwardRange& fill_n(const ForwardRange& rng, Size n, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
+ std::fill_n(boost::begin(rng), n, val);
+ return rng;
+}
+
+ } // namespace range
+ using range::fill_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find.hpp b/include/boost/range/algorithm/find.hpp
new file mode 100644
index 0000000..72c5cf1
--- /dev/null
+++ b/include/boost/range/algorithm/find.hpp
@@ -0,0 +1,80 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find
+///
+/// range-based version of the find std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+>::type
+find( SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::find(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+find( const SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::find(boost::begin(rng), boost::end(rng), val);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
+>::type
+find( SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return range_return<SinglePassRange,re>::
+ pack(std::find(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
+find( const SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return range_return<const SinglePassRange,re>::
+ pack(std::find(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+ } // namespace range
+ using range::find;
+}
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find_end.hpp b/include/boost/range/algorithm/find_end.hpp
new file mode 100644
index 0000000..757e999
--- /dev/null
+++ b/include/boost/range/algorithm/find_end.hpp
@@ -0,0 +1,152 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find_end
+///
+/// range-based version of the find_end std algorithm
+///
+/// \pre ForwardRange1 is a model of the ForwardRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type
+>::type
+find_end(ForwardRange1 & rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator< const ForwardRange1 >::type
+find_end(const ForwardRange1 & rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+>::type
+find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+ } // namespace range
+ using range::find_end;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find_first_of.hpp b/include/boost/range/algorithm/find_first_of.hpp
new file mode 100644
index 0000000..4cb5989
--- /dev/null
+++ b/include/boost/range/algorithm/find_first_of.hpp
@@ -0,0 +1,155 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find_first_of
+///
+/// range-based version of the find_first_of std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+// range return overloads
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
+>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, const ForwardRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
+find_first_of(const SinglePassRange1 & rng1, const ForwardRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+ } // namespace range
+ using range::find_first_of;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/find_if.hpp b/include/boost/range/algorithm/find_if.hpp
new file mode 100644
index 0000000..2d1926d
--- /dev/null
+++ b/include/boost/range/algorithm/find_if.hpp
@@ -0,0 +1,81 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find_if
+///
+/// range-based version of the find_if std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+>::type
+find_if( SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::find_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+find_if( const SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::find_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
+>::type
+find_if( SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return range_return<SinglePassRange,re>::
+ pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
+find_if( const SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return range_return<const SinglePassRange,re>::
+ pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::find_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/for_each.hpp b/include/boost/range/algorithm/for_each.hpp
new file mode 100644
index 0000000..ea731b2
--- /dev/null
+++ b/include/boost/range/algorithm/for_each.hpp
@@ -0,0 +1,110 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/ref.hpp>
+#include <algorithm>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+#include <xutility>
+#endif
+
+namespace boost
+{
+ namespace range
+ {
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ namespace for_each_detail
+ {
+ template<typename Iterator, typename UnaryFunction>
+ inline UnaryFunction
+ for_each_impl(Iterator first, Iterator last, UnaryFunction fun,
+ typename ::boost::enable_if<
+ is_reference_wrapper<UnaryFunction>,
+ void
+ >::type* = 0)
+ {
+ typedef typename std::_Get_unchecked_type<Iterator>::type
+ unchecked_iterator;
+
+ unchecked_iterator unchecked_last = std::_Unchecked(last);
+ for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first)
+ fun.get()(*unchecked_first);
+
+ return fun;
+ }
+
+ template<typename Iterator, typename UnaryFunction>
+ inline UnaryFunction
+ for_each_impl(Iterator first, Iterator last, UnaryFunction fn,
+ typename disable_if<
+ is_reference_wrapper<UnaryFunction>,
+ void
+ >::type* = 0)
+ {
+ return std::for_each<Iterator, UnaryFunction>(first, last, fn);
+ }
+ }
+#endif
+
+/// \brief template function for_each
+///
+/// range-based version of the for_each std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryFunction is a model of the UnaryFunctionConcept
+template< class SinglePassRange, class UnaryFunction >
+inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ return for_each_detail::for_each_impl<
+ typename range_iterator<SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng), boost::end(rng), fun);
+#else
+ return std::for_each<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng),boost::end(rng),fun);
+#endif
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryFunction >
+inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ return for_each_detail::for_each_impl<
+ typename range_iterator<const SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng), boost::end(rng), fun);
+#else
+ return std::for_each<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng), boost::end(rng), fun);
+#endif
+}
+
+ } // namespace range
+ using range::for_each;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/generate.hpp b/include/boost/range/algorithm/generate.hpp
new file mode 100644
index 0000000..324412c
--- /dev/null
+++ b/include/boost/range/algorithm/generate.hpp
@@ -0,0 +1,49 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+/// \brief template function generate
+///
+/// range-based version of the generate std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Generator is a model of the UnaryFunctionConcept
+template< class ForwardRange, class Generator >
+inline ForwardRange& generate( ForwardRange& rng, Generator gen )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::generate(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Generator >
+inline const ForwardRange& generate( const ForwardRange& rng, Generator gen )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::generate(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+ } // namespace range
+ using range::generate;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/heap_algorithm.hpp b/include/boost/range/algorithm/heap_algorithm.hpp
new file mode 100644
index 0000000..584920d
--- /dev/null
+++ b/include/boost/range/algorithm/heap_algorithm.hpp
@@ -0,0 +1,194 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function push_heap
+///
+/// range-based version of the push_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& push_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& push_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& push_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \brief template function pop_heap
+///
+/// range-based version of the pop_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& pop_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \brief template function make_heap
+///
+/// range-based version of the make_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& make_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& make_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& make_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \brief template function sort_heap
+///
+/// range-based version of the sort_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& sort_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::push_heap;
+ using range::pop_heap;
+ using range::make_heap;
+ using range::sort_heap;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/inplace_merge.hpp b/include/boost/range/algorithm/inplace_merge.hpp
new file mode 100644
index 0000000..dfadbaa
--- /dev/null
+++ b/include/boost/range/algorithm/inplace_merge.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function inplace_merge
+///
+/// range-based version of the inplace_merge std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange, class BinaryPredicate>
+inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<BidirectionalRange>::type middle,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange, class BinaryPredicate>
+inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::inplace_merge;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/lexicographical_compare.hpp b/include/boost/range/algorithm/lexicographical_compare.hpp
new file mode 100644
index 0000000..c6e4bc8
--- /dev/null
+++ b/include/boost/range/algorithm/lexicographical_compare.hpp
@@ -0,0 +1,58 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function lexicographic_compare
+///
+/// range-based version of the lexicographic_compare std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+template<class SinglePassRange1, class SinglePassRange2>
+inline bool lexicographical_compare(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::lexicographical_compare(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class BinaryPredicate>
+inline bool lexicographical_compare(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::lexicographical_compare(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+ } // namespace range
+ using range::lexicographical_compare;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/lower_bound.hpp b/include/boost/range/algorithm/lower_bound.hpp
new file mode 100644
index 0000000..cb5e639
--- /dev/null
+++ b/include/boost/range/algorithm/lower_bound.hpp
@@ -0,0 +1,124 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function lower_bound
+///
+/// range-based version of the lower_bound std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+lower_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+lower_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+lower_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+lower_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+ } // namespace range
+ using range::lower_bound;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/max_element.hpp b/include/boost/range/algorithm/max_element.hpp
new file mode 100644
index 0000000..dd2b9cb
--- /dev/null
+++ b/include/boost/range/algorithm/max_element.hpp
@@ -0,0 +1,115 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function max_element
+///
+/// range-based version of the max_element std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return boost::first_max_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return boost::first_max_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return boost::first_max_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return boost::first_max_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+max_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ boost::first_max_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+max_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ boost::first_max_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+max_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ boost::first_max_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ boost::first_max_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::max_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/merge.hpp b/include/boost/range/algorithm/merge.hpp
new file mode 100644
index 0000000..c81b8c7
--- /dev/null
+++ b/include/boost/range/algorithm/merge.hpp
@@ -0,0 +1,61 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function merge
+///
+/// range-based version of the merge std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+///
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator merge(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::merge(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator merge(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::merge(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+ } // namespace range
+ using range::merge;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/min_element.hpp b/include/boost/range/algorithm/min_element.hpp
new file mode 100644
index 0000000..339f56a
--- /dev/null
+++ b/include/boost/range/algorithm/min_element.hpp
@@ -0,0 +1,115 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function min_element
+///
+/// range-based version of the min_element std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return boost::first_min_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return boost::first_min_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return boost::first_min_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return boost::first_min_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+min_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ boost::first_min_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+min_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ boost::first_min_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+min_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ boost::first_min_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ boost::first_min_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::min_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/mismatch.hpp b/include/boost/range/algorithm/mismatch.hpp
new file mode 100644
index 0000000..2819c33
--- /dev/null
+++ b/include/boost/range/algorithm/mismatch.hpp
@@ -0,0 +1,195 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2 >
+ inline std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>
+ mismatch_impl(SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2)
+ {
+ while (first1 != last1 && first2 != last2 && *first1 == *first2)
+ {
+ ++first1;
+ ++first2;
+ }
+ return std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>(first1, first2);
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class BinaryPredicate >
+ inline std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>
+ mismatch_impl(SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ BinaryPredicate pred)
+ {
+ while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
+ {
+ ++first1;
+ ++first2;
+ }
+ return std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>(first1, first2);
+ }
+ } // namespace range_detail
+
+ namespace range
+ {
+/// \brief template function mismatch
+///
+/// range-based version of the mismatch std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+ } // namespace range
+ using range::mismatch;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/nth_element.hpp b/include/boost/range/algorithm/nth_element.hpp
new file mode 100644
index 0000000..a605595
--- /dev/null
+++ b/include/boost/range/algorithm/nth_element.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function nth_element
+///
+/// range-based version of the nth_element std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& nth_element(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& nth_element(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::nth_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/partial_sort.hpp b/include/boost/range/algorithm/partial_sort.hpp
new file mode 100644
index 0000000..d7044cd
--- /dev/null
+++ b/include/boost/range/algorithm/partial_sort.hpp
@@ -0,0 +1,76 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function partial_sort
+///
+/// range-based version of the partial_sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng),
+ sort_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng),
+ sort_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::partial_sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/partial_sort_copy.hpp b/include/boost/range/algorithm/partial_sort_copy.hpp
new file mode 100644
index 0000000..9129389
--- /dev/null
+++ b/include/boost/range/algorithm/partial_sort_copy.hpp
@@ -0,0 +1,82 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function partial_sort_copy
+///
+/// range-based version of the partial_sort_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre RandomAccessRange is a model of the Mutable_RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange, class RandomAccessRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange,
+ class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange,
+ class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+ } // namespace range
+ using range::partial_sort_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/partition.hpp b/include/boost/range/algorithm/partition.hpp
new file mode 100644
index 0000000..b814a24
--- /dev/null
+++ b/include/boost/range/algorithm/partition.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function partition
+///
+/// range-based version of the partition std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template<class ForwardRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+partition(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+/// \overload
+template<class ForwardRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+partition(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange,
+ class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+partition(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return boost::range_return<ForwardRange,re>::
+ pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange,
+ class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+partition(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return boost::range_return<const ForwardRange,re>::
+ pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
+}
+
+ } // namespace range
+ using range::partition;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/permutation.hpp b/include/boost/range/algorithm/permutation.hpp
new file mode 100644
index 0000000..75388cc
--- /dev/null
+++ b/include/boost/range/algorithm/permutation.hpp
@@ -0,0 +1,108 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function next_permutation
+///
+/// range-based version of the next_permutation std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline bool next_permutation(BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline bool next_permutation(const BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool next_permutation(BidirectionalRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool next_permutation(const BidirectionalRange& rng,
+ Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+/// \brief template function prev_permutation
+///
+/// range-based version of the prev_permutation std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline bool prev_permutation(BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline bool prev_permutation(const BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool prev_permutation(BidirectionalRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool prev_permutation(const BidirectionalRange& rng,
+ Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+ } // namespace range
+ using range::next_permutation;
+ using range::prev_permutation;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/random_shuffle.hpp b/include/boost/range/algorithm/random_shuffle.hpp
new file mode 100644
index 0000000..2475173
--- /dev/null
+++ b/include/boost/range/algorithm/random_shuffle.hpp
@@ -0,0 +1,141 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
+#include <cstdlib>
+#endif
+
+namespace boost
+{
+ namespace range
+ {
+
+ namespace detail
+ {
+#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
+
+// wrap std::rand as UniformRandomBitGenerator
+struct wrap_rand
+{
+ typedef unsigned int result_type;
+
+ static result_type (min)()
+ {
+ return 0;
+ }
+
+ static result_type (max)()
+ {
+ return RAND_MAX;
+ }
+
+ result_type operator()()
+ {
+ return std::rand();
+ }
+};
+
+template< class RandomIt >
+inline void random_shuffle(RandomIt first, RandomIt last)
+{
+ std::shuffle(first, last, wrap_rand());
+}
+
+// wrap Generator as UniformRandomBitGenerator
+template< class Generator >
+struct wrap_generator
+{
+ typedef unsigned int result_type;
+ static const int max_arg = ((0u - 1u) >> 2) + 1;
+ Generator& g;
+
+ wrap_generator(Generator& gen) : g(gen) {}
+
+ static result_type (min)()
+ {
+ return 0;
+ }
+
+ static result_type (max)()
+ {
+ return max_arg - 1;
+ }
+
+ result_type operator()()
+ {
+ return static_cast<result_type>(g(max_arg));
+ }
+};
+
+template< class RandomIt, class Generator >
+inline void random_shuffle(RandomIt first, RandomIt last, Generator& gen)
+{
+ std::shuffle(first, last, wrap_generator< Generator >(gen));
+}
+
+#else
+
+using std::random_shuffle;
+
+#endif
+ } // namespace detail
+
+/// \brief template function random_shuffle
+///
+/// range-based version of the random_shuffle std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Generator is a model of the UnaryFunctionConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ detail::random_shuffle(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ detail::random_shuffle(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Generator>
+inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Generator>
+inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+ } // namespace range
+ using range::random_shuffle;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove.hpp b/include/boost/range/algorithm/remove.hpp
new file mode 100644
index 0000000..699a7cd
--- /dev/null
+++ b/include/boost/range/algorithm/remove.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function remove
+///
+/// range-based version of the remove std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+remove(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::remove(boost::begin(rng),boost::end(rng),val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+remove(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::remove(boost::begin(rng),boost::end(rng),val);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+remove(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::remove(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+remove(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::remove(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+ } // namespace range
+ using range::remove;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove_copy.hpp b/include/boost/range/algorithm/remove_copy.hpp
new file mode 100644
index 0000000..b65747e
--- /dev/null
+++ b/include/boost/range/algorithm/remove_copy.hpp
@@ -0,0 +1,44 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function remove_copy
+///
+/// range-based version of the remove_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre Value is a model of the EqualityComparableConcept
+/// \pre Objects of type Value can be compared for equality with objects of
+/// InputIterator's value type.
+template< class SinglePassRange, class OutputIterator, class Value >
+inline OutputIterator
+remove_copy(const SinglePassRange& rng, OutputIterator out_it, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::remove_copy(boost::begin(rng), boost::end(rng), out_it, val);
+}
+
+ } // namespace range
+ using range::remove_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove_copy_if.hpp b/include/boost/range/algorithm/remove_copy_if.hpp
new file mode 100644
index 0000000..8d9c37b
--- /dev/null
+++ b/include/boost/range/algorithm/remove_copy_if.hpp
@@ -0,0 +1,38 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ /// \brief template function remove_copy_if
+ ///
+ /// range-based version of the remove_copy_if std algorithm
+ ///
+ /// \pre SinglePassRange is a model of the SinglePassRangeConcept
+ /// \pre OutputIterator is a model of the OutputIteratorConcept
+ /// \pre Predicate is a model of the PredicateConcept
+ /// \pre InputIterator's value type is convertible to Predicate's argument type
+ /// \pre out_it is not an iterator in the range rng
+ template< class SinglePassRange, class OutputIterator, class Predicate >
+ inline OutputIterator
+ remove_copy_if(const SinglePassRange& rng, OutputIterator out_it, Predicate pred)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::remove_copy_if(boost::begin(rng), boost::end(rng), out_it, pred);
+ }
+}
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/remove_if.hpp b/include/boost/range/algorithm/remove_if.hpp
new file mode 100644
index 0000000..a965df0
--- /dev/null
+++ b/include/boost/range/algorithm/remove_if.hpp
@@ -0,0 +1,75 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function remove_if
+///
+/// range-based version of the remove_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+remove_if(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::remove_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+remove_if(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::remove_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+remove_if(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::remove_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+remove_if(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::remove_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::remove_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace.hpp b/include/boost/range/algorithm/replace.hpp
new file mode 100644
index 0000000..44d3e4c
--- /dev/null
+++ b/include/boost/range/algorithm/replace.hpp
@@ -0,0 +1,53 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace
+///
+/// range-based version of the replace std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline ForwardRange&
+replace(ForwardRange& rng, const Value& what,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::replace(boost::begin(rng), boost::end(rng), what, with_what);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline const ForwardRange&
+replace(const ForwardRange& rng, const Value& what,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::replace(boost::begin(rng), boost::end(rng), what, with_what);
+ return rng;
+}
+
+ } // namespace range
+ using range::replace;
+} // namespace boost;
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace_copy.hpp b/include/boost/range/algorithm/replace_copy.hpp
new file mode 100644
index 0000000..0c02005
--- /dev/null
+++ b/include/boost/range/algorithm/replace_copy.hpp
@@ -0,0 +1,42 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace_copy
+///
+/// range-based version of the replace_copy std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class OutputIterator, class Value >
+inline OutputIterator
+replace_copy(const ForwardRange& rng, OutputIterator out_it, const Value& what,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::replace_copy(boost::begin(rng), boost::end(rng), out_it,
+ what, with_what);
+}
+
+ } // namespace range
+ using range::replace_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace_copy_if.hpp b/include/boost/range/algorithm/replace_copy_if.hpp
new file mode 100644
index 0000000..d313151
--- /dev/null
+++ b/include/boost/range/algorithm/replace_copy_if.hpp
@@ -0,0 +1,46 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace_copy_if
+///
+/// range-based version of the replace_copy_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Predicate is a model of the PredicateConcept
+/// \pre Value is convertible to Predicate's argument type
+/// \pre Value is Assignable
+/// \pre Value is convertible to a type in OutputIterator's set of value types.
+template< class ForwardRange, class OutputIterator, class Predicate, class Value >
+inline OutputIterator
+replace_copy_if(const ForwardRange& rng, OutputIterator out_it, Predicate pred,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::replace_copy_if(boost::begin(rng), boost::end(rng), out_it,
+ pred, with_what);
+}
+
+ } // namespace range
+ using range::replace_copy_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/replace_if.hpp b/include/boost/range/algorithm/replace_if.hpp
new file mode 100644
index 0000000..93d5a1f
--- /dev/null
+++ b/include/boost/range/algorithm/replace_if.hpp
@@ -0,0 +1,54 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace_if
+///
+/// range-based version of the replace_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class ForwardRange, class UnaryPredicate, class Value >
+inline ForwardRange&
+ replace_if(ForwardRange& rng, UnaryPredicate pred,
+ const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class UnaryPredicate, class Value >
+inline const ForwardRange&
+ replace_if(const ForwardRange& rng, UnaryPredicate pred,
+ const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
+ return rng;
+}
+
+ } // namespace range
+ using range::replace_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/reverse.hpp b/include/boost/range/algorithm/reverse.hpp
new file mode 100644
index 0000000..20a7eb1
--- /dev/null
+++ b/include/boost/range/algorithm/reverse.hpp
@@ -0,0 +1,50 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function reverse
+///
+/// range-based version of the reverse std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+template<class BidirectionalRange>
+inline BidirectionalRange& reverse(BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ std::reverse(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline const BidirectionalRange& reverse(const BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ std::reverse(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+ } // namespace range
+ using range::reverse;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/reverse_copy.hpp b/include/boost/range/algorithm/reverse_copy.hpp
new file mode 100644
index 0000000..f1990ad
--- /dev/null
+++ b/include/boost/range/algorithm/reverse_copy.hpp
@@ -0,0 +1,40 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function reverse_copy
+///
+/// range-based version of the reverse_copy std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+template<class BidirectionalRange, class OutputIterator>
+inline OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::reverse_copy(boost::begin(rng), boost::end(rng), out);
+}
+
+ } // namespace range
+ using range::reverse_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/rotate.hpp b/include/boost/range/algorithm/rotate.hpp
new file mode 100644
index 0000000..ca4b223
--- /dev/null
+++ b/include/boost/range/algorithm/rotate.hpp
@@ -0,0 +1,51 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function rotate
+///
+/// range-based version of the rotate std algorithm
+///
+/// \pre Rng meets the requirements for a Forward range
+template<class ForwardRange>
+inline ForwardRange& rotate(ForwardRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::rotate(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class ForwardRange>
+inline const ForwardRange& rotate(const ForwardRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::rotate(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+ } // namespace range
+ using range::rotate;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/rotate_copy.hpp b/include/boost/range/algorithm/rotate_copy.hpp
new file mode 100644
index 0000000..0409ac5
--- /dev/null
+++ b/include/boost/range/algorithm/rotate_copy.hpp
@@ -0,0 +1,44 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+ /// \brief template function rotate
+ ///
+ /// range-based version of the rotate std algorithm
+ ///
+ /// \pre Rng meets the requirements for a Forward range
+ template<typename ForwardRange, typename OutputIterator>
+ inline OutputIterator rotate_copy(
+ const ForwardRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle,
+ OutputIterator target
+ )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::rotate_copy(boost::begin(rng), middle, boost::end(rng), target);
+ }
+
+ } // namespace range
+ using range::rotate_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/search.hpp b/include/boost/range/algorithm/search.hpp
new file mode 100644
index 0000000..28cc6e6
--- /dev/null
+++ b/include/boost/range/algorithm/search.hpp
@@ -0,0 +1,134 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function search
+///
+/// range-based version of the search std algorithm
+///
+/// \pre ForwardRange1 is a model of the ForwardRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<const ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<const ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred),
+ rng1);
+}
+
+ } // namespace range
+ using range::search;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/search_n.hpp b/include/boost/range/algorithm/search_n.hpp
new file mode 100644
index 0000000..ccfb27a
--- /dev/null
+++ b/include/boost/range/algorithm/search_n.hpp
@@ -0,0 +1,360 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <boost/range/value_type.hpp>
+#include <iterator>
+#include <algorithm>
+
+namespace boost
+{
+
+namespace range_detail
+{
+ // Rationale: search_n is implemented rather than delegate to
+ // the standard library implementation because some standard
+ // library implementations are broken eg. MSVC.
+
+ // search_n forward iterator version
+ template<typename ForwardIterator, typename Integer, typename Value>
+ inline ForwardIterator
+ search_n_impl(ForwardIterator first, ForwardIterator last, Integer count,
+ const Value& value, std::forward_iterator_tag)
+ {
+ first = std::find(first, last, value);
+ while (first != last)
+ {
+ typename std::iterator_traits<ForwardIterator>::difference_type n = count;
+ ForwardIterator i = first;
+ ++i;
+ while (i != last && n != 1 && *i==value)
+ {
+ ++i;
+ --n;
+ }
+ if (n == 1)
+ return first;
+ if (i == last)
+ return last;
+ first = std::find(++i, last, value);
+ }
+ return last;
+ }
+
+ // search_n random-access iterator version
+ template<typename RandomAccessIterator, typename Integer, typename Value>
+ inline RandomAccessIterator
+ search_n_impl(RandomAccessIterator first, RandomAccessIterator last,
+ Integer count, const Value& value,
+ std::random_access_iterator_tag)
+ {
+ typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
+
+ difference_t tail_size = last - first;
+ const difference_t pattern_size = count;
+
+ if (tail_size < pattern_size)
+ return last;
+
+ const difference_t skip_offset = pattern_size - 1;
+ RandomAccessIterator look_ahead = first + skip_offset;
+ tail_size -= pattern_size;
+
+ while (1)
+ {
+ // look_ahead here is pointing to the last element of the
+ // next possible match
+ while (!(*look_ahead == value)) // skip loop...
+ {
+ if (tail_size < pattern_size)
+ return last; // no match
+ look_ahead += pattern_size;
+ tail_size -= pattern_size;
+ }
+ difference_t remainder = skip_offset;
+ for (RandomAccessIterator back_track = look_ahead - 1;
+ *back_track == value; --back_track)
+ {
+ if (--remainder == 0)
+ {
+ return look_ahead - skip_offset; // matched
+ }
+ }
+ if (remainder > tail_size)
+ return last; // no match
+ look_ahead += remainder;
+ tail_size -= remainder;
+ }
+
+ return last;
+ }
+
+ // search_n for forward iterators using a binary predicate
+ // to determine a match
+ template<typename ForwardIterator, typename Integer, typename Value,
+ typename BinaryPredicate>
+ inline ForwardIterator
+ search_n_pred_impl(ForwardIterator first, ForwardIterator last,
+ Integer count, const Value& value,
+ BinaryPredicate pred, std::forward_iterator_tag)
+ {
+ typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
+
+ while (first != last && !static_cast<bool>(pred(*first, value)))
+ ++first;
+
+ while (first != last)
+ {
+ difference_t n = count;
+ ForwardIterator i = first;
+ ++i;
+ while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
+ {
+ ++i;
+ --n;
+ }
+ if (n == 1)
+ return first;
+ if (i == last)
+ return last;
+ first = ++i;
+ while (first != last && !static_cast<bool>(pred(*first, value)))
+ ++first;
+ }
+ return last;
+ }
+
+ // search_n for random-access iterators using a binary predicate
+ // to determine a match
+ template<typename RandomAccessIterator, typename Integer,
+ typename Value, typename BinaryPredicate>
+ inline RandomAccessIterator
+ search_n_pred_impl(RandomAccessIterator first, RandomAccessIterator last,
+ Integer count, const Value& value,
+ BinaryPredicate pred, std::random_access_iterator_tag)
+ {
+ typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
+
+ difference_t tail_size = last - first;
+ const difference_t pattern_size = count;
+
+ if (tail_size < pattern_size)
+ return last;
+
+ const difference_t skip_offset = pattern_size - 1;
+ RandomAccessIterator look_ahead = first + skip_offset;
+ tail_size -= pattern_size;
+
+ while (1)
+ {
+ // look_ahead points to the last element of the next
+ // possible match
+ while (!static_cast<bool>(pred(*look_ahead, value))) // skip loop
+ {
+ if (tail_size < pattern_size)
+ return last; // no match
+ look_ahead += pattern_size;
+ tail_size -= pattern_size;
+ }
+ difference_t remainder = skip_offset;
+ for (RandomAccessIterator back_track = look_ahead - 1;
+ pred(*back_track, value); --back_track)
+ {
+ if (--remainder == 0)
+ return look_ahead -= skip_offset; // success
+ }
+ if (remainder > tail_size)
+ {
+ return last; // no match
+ }
+ look_ahead += remainder;
+ tail_size -= remainder;
+ }
+ }
+
+ template<typename ForwardIterator, typename Integer, typename Value>
+ inline ForwardIterator
+ search_n_impl(ForwardIterator first, ForwardIterator last,
+ Integer count, const Value& value)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<Value>));
+ BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<typename std::iterator_traits<ForwardIterator>::value_type>));
+ //BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2<typename std::iterator_traits<ForwardIterator>::value_type, Value>));
+
+ typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
+
+ if (count <= 0)
+ return first;
+ if (count == 1)
+ return std::find(first, last, value);
+ return range_detail::search_n_impl(first, last, count, value, cat_t());
+ }
+
+ template<typename ForwardIterator, typename Integer, typename Value,
+ typename BinaryPredicate>
+ inline ForwardIterator
+ search_n_pred_impl(ForwardIterator first, ForwardIterator last,
+ Integer count, const Value& value,
+ BinaryPredicate pred)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((
+ BinaryPredicateConcept<
+ BinaryPredicate,
+ typename std::iterator_traits<ForwardIterator>::value_type,
+ Value>
+ ));
+
+ typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
+
+ if (count <= 0)
+ return first;
+ if (count == 1)
+ {
+ while (first != last && !static_cast<bool>(pred(*first, value)))
+ ++first;
+ return first;
+ }
+ return range_detail::search_n_pred_impl(first, last, count,
+ value, pred, cat_t());
+ }
+} // namespace range_detail
+
+namespace range {
+
+/// \brief template function search
+///
+/// range-based version of the search std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Integer is an integral type
+/// \pre Value is a model of the EqualityComparableConcept
+/// \pre ForwardRange's value type is a model of the EqualityComparableConcept
+/// \pre Object's of ForwardRange's value type can be compared for equality with Objects of type Value
+template< class ForwardRange, class Integer, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ return range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate binary_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
+ return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
+ count, value, binary_pred);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate binary_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
+ return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
+ count, value, binary_pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+search_n(ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<ForwardRange,re>::
+ pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
+ count, value),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ return range_return<const ForwardRange,re>::
+ pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
+ count, value),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+search_n(ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
+ const Value&>));
+ return range_return<ForwardRange,re>::
+ pack(range_detail::search_n_pred_impl(boost::begin(rng),
+ boost::end(rng),
+ count, value, pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
+ const Value&>));
+ return range_return<const ForwardRange,re>::
+ pack(range_detail::search_n_pred_impl(boost::begin(rng),
+ boost::end(rng),
+ count, value, pred),
+ rng);
+}
+
+ } // namespace range
+ using range::search_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/set_algorithm.hpp b/include/boost/range/algorithm/set_algorithm.hpp
new file mode 100644
index 0000000..82ef8ec
--- /dev/null
+++ b/include/boost/range/algorithm/set_algorithm.hpp
@@ -0,0 +1,198 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function includes
+///
+/// range-based version of the includes std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2>
+inline bool includes(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::includes(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class BinaryPredicate>
+inline bool includes(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::includes(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+/// \brief template function set_union
+///
+/// range-based version of the set_union std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator set_union(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_union(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_union(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_union(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+/// \brief template function set_intersection
+///
+/// range-based version of the set_intersection std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator set_intersection(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_intersection(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_intersection(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_intersection(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2),
+ out, pred);
+}
+
+/// \brief template function set_difference
+///
+/// range-based version of the set_difference std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator set_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_difference(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_difference(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+/// \brief template function set_symmetric_difference
+///
+/// range-based version of the set_symmetric_difference std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_symmetric_difference(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+ } // namespace range
+ using range::includes;
+ using range::set_union;
+ using range::set_intersection;
+ using range::set_difference;
+ using range::set_symmetric_difference;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/sort.hpp b/include/boost/range/algorithm/sort.hpp
new file mode 100644
index 0000000..45eecde
--- /dev/null
+++ b/include/boost/range/algorithm/sort.hpp
@@ -0,0 +1,68 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function sort
+///
+/// range-based version of the sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& sort(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& sort(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng), pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng), pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/stable_partition.hpp b/include/boost/range/algorithm/stable_partition.hpp
new file mode 100644
index 0000000..24febfc
--- /dev/null
+++ b/include/boost/range/algorithm/stable_partition.hpp
@@ -0,0 +1,73 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function stable_partition
+///
+/// range-based version of the stable_partition std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template<class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type
+stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::stable_partition(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const BidirectionalRange>::type
+stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::stable_partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<BidirectionalRange,re>::type
+stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return range_return<BidirectionalRange,re>::pack(
+ std::stable_partition(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const BidirectionalRange,re>::type
+stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return range_return<const BidirectionalRange,re>::pack(
+ std::stable_partition(boost::begin(rng),boost::end(rng),pred),
+ rng);
+}
+
+ } // namespace range
+ using range::stable_partition;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/stable_sort.hpp b/include/boost/range/algorithm/stable_sort.hpp
new file mode 100644
index 0000000..d18da4d
--- /dev/null
+++ b/include/boost/range/algorithm/stable_sort.hpp
@@ -0,0 +1,68 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function stable_sort
+///
+/// range-based version of the stable_sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& stable_sort(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::stable_sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/swap_ranges.hpp b/include/boost/range/algorithm/swap_ranges.hpp
new file mode 100644
index 0000000..52b0162
--- /dev/null
+++ b/include/boost/range/algorithm/swap_ranges.hpp
@@ -0,0 +1,132 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<class Iterator1, class Iterator2>
+ void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
+ Iterator2 it2, Iterator2 last2,
+ single_pass_traversal_tag,
+ single_pass_traversal_tag)
+ {
+ ignore_unused_variable_warning(last2);
+ for (; it1 != last1; ++it1, ++it2)
+ {
+ BOOST_ASSERT( it2 != last2 );
+ std::iter_swap(it1, it2);
+ }
+ }
+
+ template<class Iterator1, class Iterator2>
+ void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
+ Iterator2 it2, Iterator2 last2,
+ random_access_traversal_tag,
+ random_access_traversal_tag)
+ {
+ ignore_unused_variable_warning(last2);
+ BOOST_ASSERT( last2 - it2 >= last1 - it1 );
+ std::swap_ranges(it1, last1, it2);
+ }
+
+ template<class Iterator1, class Iterator2>
+ void swap_ranges_impl(Iterator1 first1, Iterator1 last1,
+ Iterator2 first2, Iterator2 last2)
+ {
+ swap_ranges_impl(first1, last1, first2, last2,
+ BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator1>::type(),
+ BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator2>::type());
+ }
+ } // namespace range_detail
+
+ namespace range
+ {
+
+/// \brief template function swap_ranges
+///
+/// range-based version of the swap_ranges std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+template< class SinglePassRange1, class SinglePassRange2 >
+inline SinglePassRange2&
+swap_ranges(SinglePassRange1& range1, SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline SinglePassRange2&
+swap_ranges(const SinglePassRange1& range1, SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline const SinglePassRange2&
+swap_ranges(SinglePassRange1& range1, const SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline const SinglePassRange2&
+swap_ranges(const SinglePassRange1& range1, const SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+ } // namespace range
+ using range::swap_ranges;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/transform.hpp b/include/boost/range/algorithm/transform.hpp
new file mode 100644
index 0000000..ade147a
--- /dev/null
+++ b/include/boost/range/algorithm/transform.hpp
@@ -0,0 +1,96 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+ /// \brief template function transform
+ ///
+ /// range-based version of the transform std algorithm
+ ///
+ /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+ /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+ /// \pre OutputIterator is a model of the OutputIteratorConcept
+ /// \pre UnaryOperation is a model of the UnaryFunctionConcept
+ /// \pre BinaryOperation is a model of the BinaryFunctionConcept
+ template< class SinglePassRange1,
+ class OutputIterator,
+ class UnaryOperation >
+ inline OutputIterator
+ transform(const SinglePassRange1& rng,
+ OutputIterator out,
+ UnaryOperation fun)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ return std::transform(boost::begin(rng),boost::end(rng),out,fun);
+ }
+
+ } // namespace range
+
+ namespace range_detail
+ {
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class OutputIterator,
+ class BinaryFunction >
+ inline OutputIterator
+ transform_impl(SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ OutputIterator out,
+ BinaryFunction fn)
+ {
+ for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+ {
+ *out = fn(*first1, *first2);
+ ++out;
+ }
+ return out;
+ }
+ }
+
+ namespace range
+ {
+
+ /// \overload
+ template< class SinglePassRange1,
+ class SinglePassRange2,
+ class OutputIterator,
+ class BinaryOperation >
+ inline OutputIterator
+ transform(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryOperation fun)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return boost::range_detail::transform_impl(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2),
+ out, fun);
+ }
+
+ } // namespace range
+ using range::transform;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/unique.hpp b/include/boost/range/algorithm/unique.hpp
new file mode 100644
index 0000000..8017a83
--- /dev/null
+++ b/include/boost/range/algorithm/unique.hpp
@@ -0,0 +1,107 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function unique
+///
+/// range-based version of the unique std algorithm
+///
+/// \pre Rng meets the requirements for a Forward range
+template< range_return_value re, class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+unique( ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack( std::unique( boost::begin(rng),
+ boost::end(rng)), rng );
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+unique( const ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack( std::unique( boost::begin(rng),
+ boost::end(rng)), rng );
+}
+/// \overload
+template< range_return_value re, class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+unique( ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::unique(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+/// \overload
+template< range_return_value re, class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+unique( const ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::unique(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template< class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
+unique( ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
+unique( const ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
+unique( ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng, pred);
+}
+/// \overload
+template< class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
+unique( const ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng, pred);
+}
+
+ } // namespace range
+ using range::unique;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/unique_copy.hpp b/include/boost/range/algorithm/unique_copy.hpp
new file mode 100644
index 0000000..0682d74
--- /dev/null
+++ b/include/boost/range/algorithm/unique_copy.hpp
@@ -0,0 +1,51 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function unique_copy
+///
+/// range-based version of the unique_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange, class OutputIterator >
+inline OutputIterator
+unique_copy( const SinglePassRange& rng, OutputIterator out_it )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::unique_copy(boost::begin(rng), boost::end(rng), out_it);
+}
+/// \overload
+template< class SinglePassRange, class OutputIterator, class BinaryPredicate >
+inline OutputIterator
+unique_copy( const SinglePassRange& rng, OutputIterator out_it,
+ BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::unique_copy(boost::begin(rng), boost::end(rng), out_it, pred);
+}
+
+ } // namespace range
+ using range::unique_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/include/boost/range/algorithm/upper_bound.hpp b/include/boost/range/algorithm/upper_bound.hpp
new file mode 100644
index 0000000..c8acbc6
--- /dev/null
+++ b/include/boost/range/algorithm/upper_bound.hpp
@@ -0,0 +1,127 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function upper_bound
+///
+/// range-based version of the upper_bound std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline
+BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+upper_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+upper_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+upper_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+upper_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value,
+ class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value,
+ class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+ } // namespace range
+ using range::upper_bound;
+} // namespace boost
+
+#endif // include guard