diff --git a/boost/range.hpp b/boost/range.hpp new file mode 100644 index 0000000..179ae22 --- /dev/null +++ b/boost/range.hpp @@ -0,0 +1,23 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_HPP_27_07_04 +#define BOOST_RANGE_HPP_27_07_04 + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + +#endif diff --git a/boost/range/adaptor/adjacent_filtered.hpp b/boost/range/adaptor/adjacent_filtered.hpp new file mode 100644 index 0000000..287a4ae --- /dev/null +++ b/boost/range/adaptor/adjacent_filtered.hpp @@ -0,0 +1,237 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP +#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP + +#include +#ifdef BOOST_MSVC +#pragma warning( push ) +#pragma warning( disable : 4355 ) +#endif + +#include +#include +#include +#include +#include +#include +#include + + +namespace boost +{ + namespace range_detail + { + template< class Iter, class Pred, bool default_pass > + class skip_iterator + : public boost::iterator_adaptor< + skip_iterator, + Iter, + BOOST_DEDUCED_TYPENAME std::iterator_traits::value_type, + boost::forward_traversal_tag, + BOOST_DEDUCED_TYPENAME std::iterator_traits::reference, + BOOST_DEDUCED_TYPENAME std::iterator_traits::difference_type + > + , private Pred + { + private: + typedef boost::iterator_adaptor< + skip_iterator, + Iter, + BOOST_DEDUCED_TYPENAME std::iterator_traits::value_type, + boost::forward_traversal_tag, + BOOST_DEDUCED_TYPENAME std::iterator_traits::reference, + BOOST_DEDUCED_TYPENAME std::iterator_traits::difference_type + > base_t; + + public: + typedef Pred pred_t; + typedef Iter iter_t; + + skip_iterator() : m_last() {} + + skip_iterator(iter_t it, iter_t last, const Pred& pred) + : base_t(it) + , pred_t(pred) + , m_last(last) + { + } + + template + skip_iterator( const skip_iterator& other ) + : base_t(other.base()) + , pred_t(other) + , m_last(other.m_last) + { + } + + void increment() + { + iter_t& it = this->base_reference(); + BOOST_ASSERT( it != m_last ); + pred_t& bi_pred = *this; + iter_t prev = it; + ++it; + if (it != m_last) + { + if (default_pass) + { + while (it != m_last && !bi_pred(*prev, *it)) + { + ++it; + ++prev; + } + } + else + { + for (; it != m_last; ++it, ++prev) + { + if (bi_pred(*prev, *it)) + { + break; + } + } + } + } + } + + iter_t m_last; + }; + + template< class P, class R, bool default_pass > + struct adjacent_filtered_range + : iterator_range< skip_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + P, + default_pass + > + > + { + private: + typedef skip_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + P, + default_pass + > + skip_iter; + + typedef iterator_range + base_range; + + typedef BOOST_DEDUCED_TYPENAME range_iterator::type raw_iterator; + + public: + adjacent_filtered_range( const P& p, R& r ) + : base_range(skip_iter(boost::begin(r), boost::end(r), p), + skip_iter(boost::end(r), boost::end(r), p)) + { + } + }; + + template< class T > + struct adjacent_holder : holder + { + adjacent_holder( T r ) : holder(r) + { } + }; + + template< class T > + struct adjacent_excl_holder : holder + { + adjacent_excl_holder( T r ) : holder(r) + { } + }; + + template< class ForwardRng, class BinPredicate > + inline adjacent_filtered_range + operator|( ForwardRng& r, + const adjacent_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + + return adjacent_filtered_range( f.val, r ); + } + + template< class ForwardRng, class BinPredicate > + inline adjacent_filtered_range + operator|( const ForwardRng& r, + const adjacent_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + + return adjacent_filtered_range( f.val, r ); + } + + template< class ForwardRng, class BinPredicate > + inline adjacent_filtered_range + operator|( ForwardRng& r, + const adjacent_excl_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return adjacent_filtered_range( f.val, r ); + } + + template< class ForwardRng, class BinPredicate > + inline adjacent_filtered_range + operator|( const ForwardRng& r, + const adjacent_excl_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return adjacent_filtered_range( f.val, r ); + } + + } // 'range_detail' + + // Bring adjacent_filter_range into the boost namespace so that users of + // this library may specify the return type of the '|' operator and + // adjacent_filter() + using range_detail::adjacent_filtered_range; + + namespace adaptors + { + namespace + { + const range_detail::forwarder + adjacent_filtered = + range_detail::forwarder(); + + const range_detail::forwarder + adjacent_filtered_excl = + range_detail::forwarder(); + } + + template + inline adjacent_filtered_range + adjacent_filter(ForwardRng& rng, BinPredicate filter_pred) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return adjacent_filtered_range(filter_pred, rng); + } + + template + inline adjacent_filtered_range + adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return adjacent_filtered_range(filter_pred, rng); + } + + } // 'adaptors' + +} + +#ifdef BOOST_MSVC +#pragma warning( pop ) +#endif + +#endif diff --git a/boost/range/adaptor/argument_fwd.hpp b/boost/range/adaptor/argument_fwd.hpp new file mode 100644 index 0000000..fbfd40c --- /dev/null +++ b/boost/range/adaptor/argument_fwd.hpp @@ -0,0 +1,80 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP +#define BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP + +#include + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable : 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + namespace range_detail + { + template< class T > + struct holder + { + T val; + holder( T t ) : val(t) + { } + }; + + template< class T > + struct holder2 + { + T val1, val2; + holder2( T t, T u ) : val1(t), val2(u) + { } + }; + + template< template class Holder > + struct forwarder + { + template< class T > + Holder operator()( T t ) const + { + return Holder(t); + } + }; + + template< template class Holder > + struct forwarder2 + { + template< class T > + Holder operator()( T t, T u ) const + { + return Holder(t,u); + } + }; + + template< template class Holder > + struct forwarder2TU + { + template< class T, class U > + Holder operator()( T t, U u ) const + { + return Holder(t, u); + } + }; + + + } + +} + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif diff --git a/boost/range/adaptor/copied.hpp b/boost/range/adaptor/copied.hpp new file mode 100644 index 0000000..f7dfbcd --- /dev/null +++ b/boost/range/adaptor/copied.hpp @@ -0,0 +1,68 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_COPIED_HPP +#define BOOST_RANGE_ADAPTOR_COPIED_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace adaptors + { + struct copied + { + copied(std::size_t t_, std::size_t u_) + : t(t_), u(u_) {} + + std::size_t t; + std::size_t u; + }; + + template + inline CopyableRandomAccessRange + operator|(const CopyableRandomAccessRange& r, const copied& f) + { + BOOST_RANGE_CONCEPT_ASSERT(( + RandomAccessRangeConcept)); + + iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator< + const CopyableRandomAccessRange + >::type + > temp(adaptors::slice(r, f.t, f.u)); + + return CopyableRandomAccessRange(temp.begin(), temp.end()); + } + + template + inline CopyableRandomAccessRange + copy(const CopyableRandomAccessRange& rng, std::size_t t, std::size_t u) + { + BOOST_RANGE_CONCEPT_ASSERT(( + RandomAccessRangeConcept)); + + iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator< + const CopyableRandomAccessRange + >::type + > temp(adaptors::slice(rng, t, u)); + + return CopyableRandomAccessRange( temp.begin(), temp.end() ); + } + } // 'adaptors' + +} + +#endif // include guard diff --git a/boost/range/adaptor/define_adaptor.hpp b/boost/range/adaptor/define_adaptor.hpp new file mode 100644 index 0000000..b228df3 --- /dev/null +++ b/boost/range/adaptor/define_adaptor.hpp @@ -0,0 +1,109 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED +#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED + +#include + +#define BOOST_DEFINE_RANGE_ADAPTOR( adaptor_name, range_adaptor ) \ + struct adaptor_name##_forwarder {}; \ + \ + template range_adaptor \ + operator|(Range& rng, adaptor_name##_forwarder) \ + { \ + return range_adaptor ( rng ); \ + } \ + \ + template range_adaptor \ + operator|(const Range& rng, adaptor_name##_forwarder) \ + { \ + return range_adaptor ( rng ); \ + } \ + \ + static adaptor_name##_forwarder adaptor_name = adaptor_name##_forwarder(); \ + \ + template \ + range_adaptor \ + make_##adaptor_name(Range& rng) \ + { \ + return range_adaptor (rng); \ + } \ + \ + template \ + range_adaptor \ + make_##adaptor_name(const Range& rng) \ + { \ + return range_adaptor (rng); \ + } + +#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \ + struct adaptor_name \ + { \ + explicit adaptor_name (arg1_type arg1_) \ + : arg1(arg1_) {} \ + arg1_type arg1; \ + }; \ + \ + template range_adaptor \ + operator|(Range& rng, adaptor_name args) \ + { \ + return range_adaptor (rng, args.arg1); \ + } \ + \ + template range_adaptor \ + operator|(const Range& rng, adaptor_name args) \ + { \ + return range_adaptor (rng, args.arg1); \ + } \ + \ + template \ + range_adaptor \ + make_##adaptor_name(Range& rng, arg1_type arg1) \ + { \ + return range_adaptor (rng, arg1); \ + } \ + \ + template \ + range_adaptor \ + make_##adaptor_name(const Range& rng, arg1_type arg1) \ + { \ + return range_adaptor (rng, arg1); \ + } + +#define BOOST_RANGE_ADAPTOR_2( adaptor_name, range_adaptor, arg1_type, arg2_type ) \ + struct adaptor_name \ + { \ + explicit adaptor_name (arg1_type arg1_, arg2_type arg2_) \ + : arg1(arg1_), arg2(arg2_) {} \ + arg1_type arg1; \ + arg2_type arg2; \ + }; \ + \ + template range_adaptor \ + operator|(Range& rng, adaptor_name args) \ + { \ + return range_adaptor (rng, args.arg1, args.arg2); \ + } \ + template \ + range_adaptor \ + make_##adaptor_name(Range& rng, arg1_type arg1, arg2_type arg2) \ + { \ + return range_adaptor (rng, arg1, arg2); \ + } \ + template \ + range_adaptor \ + make_##adaptor_name(const Range& rng, arg1_type arg1, arg2_type arg2) \ + { \ + return range_adaptor (rng, arg1, arg2); \ + } + + +#endif // include guard diff --git a/boost/range/adaptor/filtered.hpp b/boost/range/adaptor/filtered.hpp new file mode 100644 index 0000000..b6d3ab1 --- /dev/null +++ b/boost/range/adaptor/filtered.hpp @@ -0,0 +1,118 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_FILTERED_HPP +#define BOOST_RANGE_ADAPTOR_FILTERED_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< class P, class R > + struct filtered_range : + boost::iterator_range< + boost::filter_iterator< + typename default_constructible_unary_fn_gen::type, + typename range_iterator::type + > + > + { + private: + typedef boost::iterator_range< + boost::filter_iterator< + typename default_constructible_unary_fn_gen::type, + typename range_iterator::type + > + > base; + public: + typedef typename default_constructible_unary_fn_gen::type + pred_t; + + filtered_range(P p, R& r) + : base(make_filter_iterator(pred_t(p), + boost::begin(r), boost::end(r)), + make_filter_iterator(pred_t(p), + boost::end(r), boost::end(r))) + { } + }; + + template< class T > + struct filter_holder : holder + { + filter_holder( T r ) : holder(r) + { } + }; + + template< class ForwardRange, class Predicate > + inline filtered_range + operator|(ForwardRange& r, + const filter_holder& f) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return filtered_range( f.val, r ); + } + + template< class ForwardRange, class Predicate > + inline filtered_range + operator|(const ForwardRange& r, + const filter_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + ForwardRangeConcept)); + return filtered_range( f.val, r ); + } + + } // 'range_detail' + + // Unusual use of 'using' is intended to bring filter_range into the boost namespace + // while leaving the mechanics of the '|' operator in range_detail and maintain + // argument dependent lookup. + // filter_range logically needs to be in the boost namespace to allow user of + // the library to define the return type for filter() + using range_detail::filtered_range; + + namespace adaptors + { + namespace + { + const range_detail::forwarder + filtered = + range_detail::forwarder(); + } + + template + inline filtered_range + filter(ForwardRange& rng, Predicate filter_pred) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + + return range_detail::filtered_range( filter_pred, rng ); + } + + template + inline filtered_range + filter(const ForwardRange& rng, Predicate filter_pred) + { + BOOST_RANGE_CONCEPT_ASSERT(( + ForwardRangeConcept)); + + return range_detail::filtered_range( filter_pred, rng ); + } + } // 'adaptors' + +} + +#endif diff --git a/boost/range/adaptor/formatted.hpp b/boost/range/adaptor/formatted.hpp new file mode 100644 index 0000000..f31f1bc --- /dev/null +++ b/boost/range/adaptor/formatted.hpp @@ -0,0 +1,229 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED +#define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +struct formatted_holder +{ + typedef typename boost::mpl::if_< + boost::is_array, + const typename boost::remove_extent::type*, + Sep + >::type separator_t; + + typedef typename boost::mpl::if_< + boost::is_array, + const typename boost::remove_extent::type*, + Prefix + >::type prefix_t; + + typedef typename boost::mpl::if_< + boost::is_array, + const typename boost::remove_extent::type*, + Postfix + >::type postfix_t; + + formatted_holder( + const separator_t& sep, + const prefix_t& prefix, + const postfix_t& postfix) + : m_sep(sep) + , m_prefix(prefix) + , m_postfix(postfix) + { + } + + separator_t m_sep; + prefix_t m_prefix; + postfix_t m_postfix; +}; + +template +class formatted_range + : public boost::iterator_range +{ + typedef formatted_holder holder_t; +public: + formatted_range(Iter first, Iter last, const holder_t& holder) + : boost::iterator_range(first, last) + , m_holder(holder) + { + } + + template + void write(OStream& out) const + { + Iter it(this->begin()); + out << m_holder.m_prefix; + if (it != this->end()) + { + out << *it; + for (++it; it != this->end(); ++it) + { + out << m_holder.m_sep << *it; + } + } + out << m_holder.m_postfix; + } + +private: + holder_t m_holder; +}; + +template< + typename SinglePassRange, + typename Sep, + typename Prefix, + typename Postfix +> +inline range_detail::formatted_range< + typename range_iterator::type, Sep, Prefix, Postfix +> +operator|( + const SinglePassRange& rng, + const range_detail::formatted_holder& holder +) +{ + typedef typename range_iterator::type iterator; + return range_detail::formatted_range( + boost::begin(rng), boost::end(rng), holder); +} + +template +std::basic_ostream& +operator<<( + std::basic_ostream& out, + const formatted_range& writer) +{ + writer.write(out); + return out; +} + + } // namespace range_detail + + namespace adaptors + { + +template +range_detail::formatted_holder +formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix) +{ + return range_detail::formatted_holder( + sep, prefix, postfix); +} + +template +range_detail::formatted_holder +formatted(const Sep& sep, const Prefix& prefix) +{ + return range_detail::formatted_holder(sep, prefix, '}'); +} + +template +range_detail::formatted_holder +formatted(const Sep& sep) +{ + return range_detail::formatted_holder(sep, '{', '}'); +} + +inline range_detail::formatted_holder +formatted() +{ + return range_detail::formatted_holder(',', '{', '}'); +} + +using range_detail::formatted_range; + +template +inline boost::range_detail::formatted_range< + typename boost::range_iterator::type, + Sep, Prefix, Postfix +> +format( + const SinglePassRange& rng, + const Sep& sep, + const Prefix& prefix, + const Postfix& postfix +) +{ + typedef typename boost::range_iterator::type + iterator_t; + + typedef boost::range_detail::formatted_range< + iterator_t, Sep, Prefix, Postfix> result_t; + + typedef boost::range_detail::formatted_holder + holder_t; + + return result_t(boost::begin(rng), boost::end(rng), + holder_t(sep, prefix, postfix)); +} + +template +inline boost::range_detail::formatted_range< + typename boost::range_iterator::type, + Sep, Prefix, char +> +format( + const SinglePassRange& rng, + const Sep& sep, + const Prefix& prefix) +{ + return adaptors::format(rng, sep, prefix, '}'); +} + +template +inline boost::range_detail::formatted_range< + typename boost::range_iterator::type, + Sep, char, char +> +format(const SinglePassRange& rng, const Sep& sep) +{ + return adaptors::format(rng, sep, '{', '}'); +} + +template +inline boost::range_detail::formatted_range< + typename boost::range_iterator::type, + char, char, char +> +format(const SinglePassRange& rng) +{ + return adaptors::format(rng, ',', '{', '}'); +} + + } // namespace adaptors + + namespace range + { + using boost::range_detail::formatted_range; + } // namespace range +} // namespace boost + +#endif // include guard diff --git a/boost/range/adaptor/indexed.hpp b/boost/range/adaptor/indexed.hpp new file mode 100644 index 0000000..a426bd6 --- /dev/null +++ b/boost/range/adaptor/indexed.hpp @@ -0,0 +1,370 @@ +// Copyright 2014 Neil Groves +// +// Copyright (c) 2010 Ilya Murav'jov +// +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Credits: +// My (Neil's) first indexed adaptor was hindered by having the underlying +// iterator return the same reference as the wrapped iterator. This meant that +// to obtain the index one had to get to the index_iterator and call the +// index() function on it. Ilya politely pointed out that this was useless in +// a number of scenarios since one naturally hides the use of iterators in +// good range-based code. Ilya provided a new interface (which has remained) +// and a first implementation. Much of this original implementation has +// been simplified and now supports more compilers and platforms. +// +#ifndef BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED +#define BOOST_RANGE_ADAPTOR_INDEXED_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace boost +{ + namespace adaptors + { + +struct indexed +{ + explicit indexed(std::ptrdiff_t x = 0) + : val(x) + { + } + std::ptrdiff_t val; +}; + + } // namespace adaptors + + namespace range + { + +// Why yet another "pair" class: +// - std::pair can't store references +// - no need for typing for index type (default to "std::ptrdiff_t"); this is +// useful in BOOST_FOREACH() expressions that have pitfalls with commas +// ( see http://www.boost.org/doc/libs/1_44_0/doc/html/foreach/pitfalls.html ) +// - meaningful access functions index(), value() +template +class index_value + : public tuple +{ + typedef tuple base_t; + + template + struct iv_types + { + typedef typename tuples::element::type n_type; + + typedef typename tuples::access_traits::non_const_type non_const_type; + typedef typename tuples::access_traits::const_type const_type; + }; + +public: + typedef typename iv_types<0>::non_const_type index_type; + typedef typename iv_types<0>::const_type const_index_type; + typedef typename iv_types<1>::non_const_type value_type; + typedef typename iv_types<1>::const_type const_value_type; + + index_value() + { + } + + index_value(typename tuples::access_traits::parameter_type t0, + typename tuples::access_traits::parameter_type t1) + : base_t(t0, t1) + { + } + + // member functions index(), value() (non-const and const) + index_type index() + { + return boost::tuples::get<0>(*this); + } + + const_index_type index() const + { + return boost::tuples::get<0>(*this); + } + + value_type value() + { + return boost::tuples::get<1>(*this); + } + + const_value_type value() const + { + return boost::tuples::get<1>(*this); + } +}; + + } // namespace range + +namespace range_detail +{ + +template +struct indexed_iterator_value_type +{ + typedef ::boost::range::index_value< + typename iterator_reference::type, + typename iterator_difference::type + > type; +}; + +// Meta-function to get the traversal for the range and therefore iterator +// returned by the indexed adaptor for a specified iterator type. +// +// Random access -> Random access +// Bidirectional -> Forward +// Forward -> Forward +// SinglePass -> SinglePass +// +// The rationale for demoting a Bidirectional input to Forward is that the end +// iterator cannot cheaply have an index computed for it. Therefore I chose to +// demote to forward traversal. I can maintain the ability to traverse randomly +// when the input is Random Access since the index for the end iterator is cheap +// to compute. +template +struct indexed_traversal +{ +private: + typedef typename iterator_traversal::type wrapped_traversal; + +public: + + typedef typename mpl::if_< + is_convertible, + random_access_traversal_tag, + typename mpl::if_< + is_convertible, + forward_traversal_tag, + wrapped_traversal + >::type + >::type type; +}; + +template +class indexed_iterator + : public iterator_facade< + indexed_iterator, + typename indexed_iterator_value_type::type, + typename indexed_traversal::type, + typename indexed_iterator_value_type::type, + typename iterator_difference::type + > +{ +public: + typedef Iter wrapped; + +private: + typedef iterator_facade< + indexed_iterator, + typename indexed_iterator_value_type::type, + typename indexed_traversal::type, + typename indexed_iterator_value_type::type, + typename iterator_difference::type + > base_t; + +public: + typedef typename base_t::difference_type difference_type; + typedef typename base_t::reference reference; + typedef typename base_t::difference_type index_type; + + indexed_iterator() + : m_it() + , m_index() + { + } + + template + indexed_iterator( + const indexed_iterator& other, + typename enable_if >::type* = 0 + ) + : m_it(other.get()) + , m_index(other.get_index()) + { + } + + explicit indexed_iterator(wrapped it, index_type index) + : m_it(it) + , m_index(index) + { + } + + wrapped get() const + { + return m_it; + } + + index_type get_index() const + { + return m_index; + } + + private: + friend class boost::iterator_core_access; + + reference dereference() const + { + return reference(m_index, *m_it); + } + + bool equal(const indexed_iterator& other) const + { + return m_it == other.m_it; + } + + void increment() + { + ++m_index; + ++m_it; + } + + void decrement() + { + BOOST_ASSERT_MSG(m_index > 0, "indexed Iterator out of bounds"); + --m_index; + --m_it; + } + + void advance(index_type n) + { + m_index += n; + BOOST_ASSERT_MSG(m_index >= 0, "indexed Iterator out of bounds"); + m_it += n; + } + + difference_type distance_to(const indexed_iterator& other) const + { + return other.m_it - m_it; + } + + wrapped m_it; + index_type m_index; +}; + +template +struct indexed_range + : iterator_range< + indexed_iterator< + typename range_iterator::type + > + > +{ + typedef iterator_range< + indexed_iterator< + typename range_iterator::type + > + > base_t; + + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); +public: + typedef indexed_iterator< + typename range_iterator::type + > iterator; + + // Constructor for non-random access iterators. + // This sets the end iterator index to i despite this being incorrect it + // is never observable since bidirectional iterators are demoted to + // forward iterators. + indexed_range( + typename base_t::difference_type i, + SinglePassRange& r, + single_pass_traversal_tag + ) + : base_t(iterator(boost::begin(r), i), + iterator(boost::end(r), i)) + { + } + + indexed_range( + typename base_t::difference_type i, + SinglePassRange& r, + random_access_traversal_tag + ) + : base_t(iterator(boost::begin(r), i), + iterator(boost::end(r), i + boost::size(r))) + { + } +}; + + } // namespace range_detail + + using range_detail::indexed_range; + + namespace adaptors + { + +template +inline indexed_range +operator|(SinglePassRange& r, indexed e) +{ + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept + )); + return indexed_range( + e.val, r, + typename range_traversal::type()); +} + +template +inline indexed_range +operator|(const SinglePassRange& r, indexed e) +{ + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept + )); + return indexed_range( + e.val, r, + typename range_traversal::type()); +} + +template +inline indexed_range +index( + SinglePassRange& rng, + typename range_difference::type index_value = 0) +{ + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept + )); + return indexed_range( + index_value, rng, + typename range_traversal::type()); +} + +template +inline indexed_range +index( + const SinglePassRange& rng, + typename range_difference::type index_value = 0) +{ + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept + )); + return indexed_range( + index_value, rng, + typename range_traversal::type()); +} + + } // namespace adaptors +} // namespace boost + +#endif // include guard diff --git a/boost/range/adaptor/indirected.hpp b/boost/range/adaptor/indirected.hpp new file mode 100644 index 0000000..e741f17 --- /dev/null +++ b/boost/range/adaptor/indirected.hpp @@ -0,0 +1,100 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_INDIRECTED_HPP +#define BOOST_RANGE_ADAPTOR_INDIRECTED_HPP + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< class R > + struct indirected_range : + public boost::iterator_range< + boost::indirect_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + { + private: + typedef boost::iterator_range< + boost::indirect_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + base; + + public: + explicit indirected_range( R& r ) + : base( r ) + { } + }; + + struct indirect_forwarder {}; + + template< class SinglePassRange > + inline indirected_range + operator|( SinglePassRange& r, indirect_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return indirected_range( r ); + } + + template< class SinglePassRange > + inline indirected_range + operator|( const SinglePassRange& r, indirect_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return indirected_range( r ); + } + + } // 'range_detail' + + using range_detail::indirected_range; + + namespace adaptors + { + namespace + { + const range_detail::indirect_forwarder indirected = + range_detail::indirect_forwarder(); + } + + template + inline indirected_range + indirect(SinglePassRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + return indirected_range(rng); + } + + template + inline indirected_range + indirect(const SinglePassRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return indirected_range(rng); + } + } // 'adaptors' + +} + +#endif diff --git a/boost/range/adaptor/map.hpp b/boost/range/adaptor/map.hpp new file mode 100644 index 0000000..2d922ea --- /dev/null +++ b/boost/range/adaptor/map.hpp @@ -0,0 +1,204 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_MAP_HPP +#define BOOST_RANGE_ADAPTOR_MAP_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + struct map_keys_forwarder {}; + struct map_values_forwarder {}; + + template< class Map > + struct select_first + { + typedef BOOST_DEDUCED_TYPENAME range_reference::type argument_type; + typedef const BOOST_DEDUCED_TYPENAME range_value::type::first_type& result_type; + + result_type operator()( argument_type r ) const + { + return r.first; + } + }; + + template< class Map > + struct select_second_mutable + { + typedef BOOST_DEDUCED_TYPENAME range_reference::type argument_type; + typedef BOOST_DEDUCED_TYPENAME range_value::type::second_type& result_type; + + result_type operator()( argument_type r ) const + { + return r.second; + } + }; + + template< class Map > + struct select_second_const + { + typedef BOOST_DEDUCED_TYPENAME range_reference::type argument_type; + typedef const BOOST_DEDUCED_TYPENAME range_value::type::second_type& result_type; + + result_type operator()( argument_type r ) const + { + return r.second; + } + }; + + template + class select_first_range + : public transformed_range< + select_first, + const StdPairRng> + { + typedef transformed_range, const StdPairRng> base; + public: + typedef select_first transform_fn_type; + typedef const StdPairRng source_range_type; + + select_first_range(transform_fn_type fn, source_range_type& rng) + : base(fn, rng) + { + } + + select_first_range(const base& other) : base(other) {} + }; + + template + class select_second_mutable_range + : public transformed_range< + select_second_mutable, + StdPairRng> + { + typedef transformed_range, StdPairRng> base; + public: + typedef select_second_mutable transform_fn_type; + typedef StdPairRng source_range_type; + + select_second_mutable_range(transform_fn_type fn, source_range_type& rng) + : base(fn, rng) + { + } + + select_second_mutable_range(const base& other) : base(other) {} + }; + + template + class select_second_const_range + : public transformed_range< + select_second_const, + const StdPairRng> + { + typedef transformed_range, const StdPairRng> base; + public: + typedef select_second_const transform_fn_type; + typedef const StdPairRng source_range_type; + + select_second_const_range(transform_fn_type fn, source_range_type& rng) + : base(fn, rng) + { + } + + select_second_const_range(const base& other) : base(other) {} + }; + + template< class StdPairRng > + inline select_first_range + operator|( const StdPairRng& r, map_keys_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return operator|( r, + boost::adaptors::transformed( select_first() ) ); + } + + template< class StdPairRng > + inline select_second_mutable_range + operator|( StdPairRng& r, map_values_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + return operator|( r, + boost::adaptors::transformed( select_second_mutable() ) ); + } + + template< class StdPairRng > + inline select_second_const_range + operator|( const StdPairRng& r, map_values_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return operator|( r, + boost::adaptors::transformed( select_second_const() ) ); + } + + } // 'range_detail' + + using range_detail::select_first_range; + using range_detail::select_second_mutable_range; + using range_detail::select_second_const_range; + + namespace adaptors + { + namespace + { + const range_detail::map_keys_forwarder map_keys = + range_detail::map_keys_forwarder(); + + const range_detail::map_values_forwarder map_values = + range_detail::map_values_forwarder(); + } + + template + inline select_first_range + keys(const StdPairRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return select_first_range( + range_detail::select_first(), rng ); + } + + template + inline select_second_const_range + values(const StdPairRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return select_second_const_range( + range_detail::select_second_const(), rng ); + } + + template + inline select_second_mutable_range + values(StdPairRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + return select_second_mutable_range( + range_detail::select_second_mutable(), rng ); + } + } // 'adaptors' + +} + +#endif diff --git a/boost/range/adaptor/replaced.hpp b/boost/range/adaptor/replaced.hpp new file mode 100644 index 0000000..1950b82 --- /dev/null +++ b/boost/range/adaptor/replaced.hpp @@ -0,0 +1,169 @@ +// Boost.Range library +// +// Copyright Neil Groves 2007. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED +#define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< class Value > + class replace_value + { + public: + typedef const Value& result_type; + typedef const Value& first_argument_type; + + // Rationale: + // The default constructor is required to allow the transform + // iterator to properly model the iterator concept. + replace_value() + { + } + + replace_value(const Value& from, const Value& to) + : m_impl(data(from, to)) + { + } + + const Value& operator()(const Value& x) const + { + return (x == m_impl->m_from) ? m_impl->m_to : x; + } + + private: + struct data + { + data(const Value& from, const Value& to) + : m_from(from) + , m_to(to) + { + } + + Value m_from; + Value m_to; + }; + boost::optional m_impl; + }; + + template< class R > + class replaced_range : + public boost::iterator_range< + boost::transform_iterator< + replace_value< BOOST_DEDUCED_TYPENAME range_value::type >, + BOOST_DEDUCED_TYPENAME range_iterator::type > > + { + private: + typedef replace_value< BOOST_DEDUCED_TYPENAME range_value::type > Fn; + + typedef boost::iterator_range< + boost::transform_iterator< + replace_value< BOOST_DEDUCED_TYPENAME range_value::type >, + BOOST_DEDUCED_TYPENAME range_iterator::type > > base_t; + + public: + typedef BOOST_DEDUCED_TYPENAME range_value::type value_type; + + replaced_range( R& r, value_type from, value_type to ) + : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ), + make_transform_iterator( boost::end(r), Fn(from, to) ) ) + { } + }; + + template< class T > + class replace_holder : public holder2 + { + public: + replace_holder( const T& from, const T& to ) + : holder2(from, to) + { } + private: + // not assignable + void operator=(const replace_holder&); + }; + + template< class SinglePassRange > + inline replaced_range + operator|( + SinglePassRange& r, + const replace_holder< + BOOST_DEDUCED_TYPENAME range_value::type>& f ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return replaced_range(r, f.val1, f.val2); + } + + template< class SinglePassRange > + inline replaced_range + operator|( + const SinglePassRange& r, + const replace_holder< + BOOST_DEDUCED_TYPENAME range_value::type>& f) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return replaced_range(r, f.val1, f.val2); + } + } // 'range_detail' + + using range_detail::replaced_range; + + namespace adaptors + { + namespace + { + const range_detail::forwarder2 + replaced = + range_detail::forwarder2(); + } + + template + inline replaced_range + replace(SinglePassRange& rng, + BOOST_DEDUCED_TYPENAME range_value::type from, + BOOST_DEDUCED_TYPENAME range_value::type to) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return replaced_range(rng, from, to); + } + + template + inline replaced_range + replace(const SinglePassRange& rng, + BOOST_DEDUCED_TYPENAME range_value::type from, + BOOST_DEDUCED_TYPENAME range_value::type to) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return replaced_range(rng, from ,to); + } + + } // 'adaptors' +} // 'boost' + +#endif // include guard diff --git a/boost/range/adaptor/replaced_if.hpp b/boost/range/adaptor/replaced_if.hpp new file mode 100644 index 0000000..e425e7d --- /dev/null +++ b/boost/range/adaptor/replaced_if.hpp @@ -0,0 +1,177 @@ +// Boost.Range library +// +// Copyright Neil Groves 2007. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED +#define BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< class Pred, class Value > + class replace_value_if + { + public: + typedef const Value& result_type; + typedef const Value& first_argument_type; + + // Rationale: + // required to allow the iterator to be default constructible. + replace_value_if() + { + } + + replace_value_if(const Pred& pred, const Value& to) + : m_impl(data(pred, to)) + { + } + + const Value& operator()(const Value& x) const + { + return m_impl->m_pred(x) ? m_impl->m_to : x; + } + + private: + struct data + { + data(const Pred& p, const Value& t) + : m_pred(p), m_to(t) + { + } + + Pred m_pred; + Value m_to; + }; + boost::optional m_impl; + }; + + template< class Pred, class R > + class replaced_if_range : + public boost::iterator_range< + boost::transform_iterator< + replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value::type >, + BOOST_DEDUCED_TYPENAME range_iterator::type > > + { + private: + typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value::type > Fn; + + typedef boost::iterator_range< + boost::transform_iterator< + replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value::type >, + BOOST_DEDUCED_TYPENAME range_iterator::type > > base_t; + + public: + typedef BOOST_DEDUCED_TYPENAME range_value::type value_type; + + replaced_if_range( R& r, const Pred& pred, value_type to ) + : base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ), + make_transform_iterator( boost::end(r), Fn(pred, to) ) ) + { } + }; + + template< class Pred, class T > + class replace_if_holder + { + public: + replace_if_holder( const Pred& pred, const T& to ) + : m_pred(pred), m_to(to) + { } + + const Pred& pred() const { return m_pred; } + const T& to() const { return m_to; } + + private: + Pred m_pred; + T m_to; + }; + + template< class Pred, class SinglePassRange > + inline replaced_if_range + operator|( + SinglePassRange& r, + const replace_if_holder< + Pred, + BOOST_DEDUCED_TYPENAME range_value::type>& f) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return replaced_if_range( + r, f.pred(), f.to()); + } + + template< class Pred, class SinglePassRange > + inline replaced_if_range + operator|( + const SinglePassRange& r, + const replace_if_holder< + Pred, + BOOST_DEDUCED_TYPENAME range_value::type>& f) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return replaced_if_range( + r, f.pred(), f.to()); + } + } // 'range_detail' + + using range_detail::replaced_if_range; + + namespace adaptors + { + namespace + { + const range_detail::forwarder2TU + replaced_if = + range_detail::forwarder2TU(); + } + + template + inline replaced_if_range + replace_if(SinglePassRange& rng, Pred pred, + BOOST_DEDUCED_TYPENAME range_value::type to) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return range_detail::replaced_if_range( + rng, pred, to); + } + + template + inline replaced_if_range + replace_if( + const SinglePassRange& rng, + Pred pred, + BOOST_DEDUCED_TYPENAME range_value::type to) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return range_detail::replaced_if_range( + rng, pred, to); + } + } // 'adaptors' + +} // 'boost' + +#endif // include guard diff --git a/boost/range/adaptor/reversed.hpp b/boost/range/adaptor/reversed.hpp new file mode 100644 index 0000000..944fbff --- /dev/null +++ b/boost/range/adaptor/reversed.hpp @@ -0,0 +1,103 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_REVERSED_HPP +#define BOOST_RANGE_ADAPTOR_REVERSED_HPP + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< class R > + struct reversed_range : + public boost::iterator_range< + boost::reverse_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + { + private: + typedef boost::iterator_range< + boost::reverse_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + base; + + public: + typedef boost::reverse_iterator::type> iterator; + + explicit reversed_range( R& r ) + : base( iterator(boost::end(r)), iterator(boost::begin(r)) ) + { } + }; + + struct reverse_forwarder {}; + + template< class BidirectionalRange > + inline reversed_range + operator|( BidirectionalRange& r, reverse_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + BidirectionalRangeConcept)); + + return reversed_range( r ); + } + + template< class BidirectionalRange > + inline reversed_range + operator|( const BidirectionalRange& r, reverse_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + BidirectionalRangeConcept)); + + return reversed_range( r ); + } + + } // 'range_detail' + + using range_detail::reversed_range; + + namespace adaptors + { + namespace + { + const range_detail::reverse_forwarder reversed = + range_detail::reverse_forwarder(); + } + + template + inline reversed_range + reverse(BidirectionalRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + BidirectionalRangeConcept)); + + return reversed_range(rng); + } + + template + inline reversed_range + reverse(const BidirectionalRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + BidirectionalRangeConcept)); + + return reversed_range(rng); + } + } // 'adaptors' + +} // 'boost' + +#endif diff --git a/boost/range/adaptor/sliced.hpp b/boost/range/adaptor/sliced.hpp new file mode 100644 index 0000000..a09cbd0 --- /dev/null +++ b/boost/range/adaptor/sliced.hpp @@ -0,0 +1,96 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_SLICED_HPP +#define BOOST_RANGE_ADAPTOR_SLICED_HPP + +#include +#include +#include +#include + +namespace boost +{ + namespace adaptors + { + struct sliced + { + sliced(std::size_t t_, std::size_t u_) + : t(t_), u(u_) {} + std::size_t t; + std::size_t u; + }; + + template< class RandomAccessRange > + class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + { + typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > base_t; + public: + template + sliced_range(Rng& rng, T t, U u) + : base_t(boost::next(boost::begin(rng), t), + boost::next(boost::begin(rng), u)) + { + } + }; + + template< class RandomAccessRange > + inline sliced_range + slice( RandomAccessRange& rng, std::size_t t, std::size_t u ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + RandomAccessRangeConcept)); + + BOOST_ASSERT( t <= u && "error in slice indices" ); + BOOST_ASSERT( static_cast(boost::size(rng)) >= u && + "second slice index out of bounds" ); + + return sliced_range(rng, t, u); + } + + template< class RandomAccessRange > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + slice( const RandomAccessRange& rng, std::size_t t, std::size_t u ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + RandomAccessRangeConcept)); + + BOOST_ASSERT( t <= u && "error in slice indices" ); + BOOST_ASSERT( static_cast(boost::size(rng)) >= u && + "second slice index out of bounds" ); + + return sliced_range(rng, t, u); + } + + template< class RandomAccessRange > + inline sliced_range + operator|( RandomAccessRange& r, const sliced& f ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + RandomAccessRangeConcept)); + + return sliced_range( r, f.t, f.u ); + } + + template< class RandomAccessRange > + inline sliced_range + operator|( const RandomAccessRange& r, const sliced& f ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + RandomAccessRangeConcept)); + + return sliced_range( r, f.t, f.u ); + } + + } // namespace adaptors + using adaptors::sliced_range; +} // namespace boost + +#endif diff --git a/boost/range/adaptor/strided.hpp b/boost/range/adaptor/strided.hpp new file mode 100644 index 0000000..c5fea86 --- /dev/null +++ b/boost/range/adaptor/strided.hpp @@ -0,0 +1,697 @@ +// Boost.Range library +// +// Copyright Neil Groves 2007. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED +#define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // strided_iterator for wrapping a forward traversal iterator + template + class strided_iterator + : public iterator_facade< + strided_iterator + , typename iterator_value::type + , forward_traversal_tag + , typename iterator_reference::type + , typename iterator_difference::type + > + { + friend class ::boost::iterator_core_access; + + typedef iterator_facade< + strided_iterator + , typename iterator_value::type + , forward_traversal_tag + , typename iterator_reference::type + , typename iterator_difference::type + > super_t; + + public: + typedef typename super_t::difference_type difference_type; + typedef typename super_t::reference reference; + typedef BaseIterator base_iterator; + typedef std::forward_iterator_tag iterator_category; + + strided_iterator() + : m_it() + , m_last() + , m_stride() + { + } + + strided_iterator(base_iterator it, + base_iterator last, + difference_type stride) + : m_it(it) + , m_last(last) + , m_stride(stride) + { + } + + template + strided_iterator( + const strided_iterator& other, + typename enable_if_convertible< + OtherIterator, + base_iterator + >::type* = 0 + ) + : m_it(other.base()) + , m_last(other.base_end()) + , m_stride(other.get_stride()) + { + } + + base_iterator base() const + { + return m_it; + } + + base_iterator base_end() const + { + return m_last; + } + + difference_type get_stride() const + { + return m_stride; + } + + private: + void increment() + { + for (difference_type i = 0; + (m_it != m_last) && (i < m_stride); ++i) + { + ++m_it; + } + } + + reference dereference() const + { + return *m_it; + } + + template + bool equal( + const strided_iterator& other, + typename enable_if_convertible< + OtherIterator, + base_iterator + >::type* = 0) const + { + return m_it == other.m_it; + } + + base_iterator m_it; + base_iterator m_last; + difference_type m_stride; + }; + + // strided_iterator for wrapping a bidirectional iterator + template + class strided_iterator + : public iterator_facade< + strided_iterator + , typename iterator_value::type + , bidirectional_traversal_tag + , typename iterator_reference::type + , typename iterator_difference::type + > + { + friend class ::boost::iterator_core_access; + + typedef iterator_facade< + strided_iterator + , typename iterator_value::type + , bidirectional_traversal_tag + , typename iterator_reference::type + , typename iterator_difference::type + > super_t; + public: + typedef typename super_t::difference_type difference_type; + typedef typename super_t::reference reference; + typedef BaseIterator base_iterator; + typedef typename boost::make_unsigned::type + size_type; + typedef std::bidirectional_iterator_tag iterator_category; + + strided_iterator() + : m_it() + , m_offset() + , m_index() + , m_stride() + { + } + + strided_iterator(base_iterator it, + size_type index, + difference_type stride) + : m_it(it) + , m_offset() + , m_index(index) + , m_stride(stride) + { + if (stride && ((m_index % stride) != 0)) + m_index += (stride - (m_index % stride)); + } + + template + strided_iterator( + const strided_iterator< + OtherIterator, + bidirectional_traversal_tag + >& other, + typename enable_if_convertible< + OtherIterator, + base_iterator + >::type* = 0 + ) + : m_it(other.base()) + , m_offset(other.get_offset()) + , m_index(other.get_index()) + , m_stride(other.get_stride()) + { + } + + base_iterator base() const + { + return m_it; + } + + difference_type get_offset() const + { + return m_offset; + } + + size_type get_index() const + { + return m_index; + } + + difference_type get_stride() const + { + return m_stride; + } + + private: + void increment() + { + m_offset += m_stride; + } + + void decrement() + { + m_offset -= m_stride; + } + + reference dereference() const + { + update(); + return *m_it; + } + + void update() const + { + std::advance(m_it, m_offset); + m_index += m_offset; + m_offset = 0; + } + + template + bool equal( + const strided_iterator< + OtherIterator, + bidirectional_traversal_tag + >& other, + typename enable_if_convertible< + OtherIterator, + base_iterator + >::type* = 0) const + { + return (m_index + m_offset) == + (other.get_index() + other.get_offset()); + } + + mutable base_iterator m_it; + mutable difference_type m_offset; + mutable size_type m_index; + difference_type m_stride; + }; + + // strided_iterator implementation for wrapping a random access iterator + template + class strided_iterator + : public iterator_facade< + strided_iterator + , typename iterator_value::type + , random_access_traversal_tag + , typename iterator_reference::type + , typename iterator_difference::type + > + { + friend class ::boost::iterator_core_access; + + typedef iterator_facade< + strided_iterator + , typename iterator_value::type + , random_access_traversal_tag + , typename iterator_reference::type + , typename iterator_difference::type + > super_t; + public: + typedef typename super_t::difference_type difference_type; + typedef typename super_t::reference reference; + typedef BaseIterator base_iterator; + typedef std::random_access_iterator_tag iterator_category; + + strided_iterator() + : m_it() + , m_first() + , m_index(0) + , m_stride() + { + } + + strided_iterator( + base_iterator first, + base_iterator it, + difference_type stride + ) + : m_it(it) + , m_first(first) + , m_index(stride ? (it - first) : difference_type()) + , m_stride(stride) + { + if (stride && ((m_index % stride) != 0)) + m_index += (stride - (m_index % stride)); + } + + template + strided_iterator( + const strided_iterator< + OtherIterator, + random_access_traversal_tag + >& other, + typename enable_if_convertible< + OtherIterator, + base_iterator + >::type* = 0 + ) + : m_it(other.base()) + , m_first(other.base_begin()) + , m_index(other.get_index()) + , m_stride(other.get_stride()) + { + } + + base_iterator base_begin() const + { + return m_first; + } + + base_iterator base() const + { + return m_it; + } + + difference_type get_stride() const + { + return m_stride; + } + + difference_type get_index() const + { + return m_index; + } + + private: + void increment() + { + m_index += m_stride; + } + + void decrement() + { + m_index -= m_stride; + } + + void advance(difference_type offset) + { + m_index += (m_stride * offset); + } + + // Implementation detail: only update the actual underlying iterator + // at the point of dereference. This is done so that the increment + // and decrement can overshoot the valid sequence as is required + // by striding. Since we can do all comparisons just with the index + // simply, and all dereferences must be within the valid range. + void update() const + { + m_it = m_first + m_index; + } + + template + difference_type distance_to( + const strided_iterator< + OtherIterator, + random_access_traversal_tag + >& other, + typename enable_if_convertible< + OtherIterator, base_iterator>::type* = 0) const + { + BOOST_ASSERT((other.m_index - m_index) % m_stride == difference_type()); + return (other.m_index - m_index) / m_stride; + } + + template + bool equal( + const strided_iterator< + OtherIterator, + random_access_traversal_tag + >& other, + typename enable_if_convertible< + OtherIterator, base_iterator>::type* = 0) const + { + return m_index == other.m_index; + } + + reference dereference() const + { + update(); + return *m_it; + } + + private: + mutable base_iterator m_it; + base_iterator m_first; + difference_type m_index; + difference_type m_stride; + }; + + template inline + strided_iterator< + typename range_iterator::type, + forward_traversal_tag + > + make_begin_strided_iterator( + Rng& rng, + Difference stride, + forward_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + forward_traversal_tag + >(boost::begin(rng), boost::end(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + forward_traversal_tag + > + make_begin_strided_iterator( + const Rng& rng, + Difference stride, + forward_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + forward_traversal_tag + >(boost::begin(rng), boost::end(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + forward_traversal_tag + > + make_end_strided_iterator( + Rng& rng, + Difference stride, + forward_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + forward_traversal_tag + >(boost::end(rng), boost::end(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + forward_traversal_tag + > + make_end_strided_iterator( + const Rng& rng, + Difference stride, + forward_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + forward_traversal_tag + >(boost::end(rng), boost::end(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + > + make_begin_strided_iterator( + Rng& rng, + Difference stride, + bidirectional_traversal_tag) + { + typedef typename range_difference::type difference_type; + + return strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + >(boost::begin(rng), difference_type(), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + > + make_begin_strided_iterator( + const Rng& rng, + Difference stride, + bidirectional_traversal_tag) + { + typedef typename range_difference::type difference_type; + + return strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + >(boost::begin(rng), difference_type(), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + > + make_end_strided_iterator( + Rng& rng, + Difference stride, + bidirectional_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + >(boost::end(rng), boost::size(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + > + make_end_strided_iterator( + const Rng& rng, + Difference stride, + bidirectional_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + bidirectional_traversal_tag + >(boost::end(rng), boost::size(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + > + make_begin_strided_iterator( + Rng& rng, + Difference stride, + random_access_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + >(boost::begin(rng), boost::begin(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + > + make_begin_strided_iterator( + const Rng& rng, + Difference stride, + random_access_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + >(boost::begin(rng), boost::begin(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + > + make_end_strided_iterator( + Rng& rng, + Difference stride, + random_access_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + >(boost::begin(rng), boost::end(rng), stride); + } + + template inline + strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + > + make_end_strided_iterator( + const Rng& rng, + Difference stride, + random_access_traversal_tag) + { + return strided_iterator< + typename range_iterator::type, + random_access_traversal_tag + >(boost::begin(rng), boost::end(rng), stride); + } + + template< + class Rng, + class Category = + typename iterator_traversal< + typename range_iterator::type + >::type + > + class strided_range + : public iterator_range< + range_detail::strided_iterator< + typename range_iterator::type, + Category + > + > + { + typedef range_detail::strided_iterator< + typename range_iterator::type, + Category + > iter_type; + typedef iterator_range super_t; + public: + template + strided_range(Difference stride, Rng& rng) + : super_t( + range_detail::make_begin_strided_iterator( + rng, stride, + typename iterator_traversal< + typename range_iterator::type + >::type()), + range_detail::make_end_strided_iterator( + rng, stride, + typename iterator_traversal< + typename range_iterator::type + >::type())) + { + BOOST_ASSERT( stride >= 0 ); + } + }; + + template + class strided_holder : public holder + { + public: + explicit strided_holder(Difference value) + : holder(value) + { + } + }; + + template + inline strided_range + operator|(Rng& rng, const strided_holder& stride) + { + return strided_range(stride.val, rng); + } + + template + inline strided_range + operator|(const Rng& rng, const strided_holder& stride) + { + return strided_range(stride.val, rng); + } + + } // namespace range_detail + + using range_detail::strided_range; + + namespace adaptors + { + + namespace + { + const range_detail::forwarder + strided = range_detail::forwarder< + range_detail::strided_holder>(); + } + + template + inline strided_range + stride(Range& rng, Difference step) + { + return strided_range(step, rng); + } + + template + inline strided_range + stride(const Range& rng, Difference step) + { + return strided_range(step, rng); + } + + } // namespace 'adaptors' +} // namespace 'boost' + +#endif diff --git a/boost/range/adaptor/tokenized.hpp b/boost/range/adaptor/tokenized.hpp new file mode 100644 index 0000000..f0aa12e --- /dev/null +++ b/boost/range/adaptor/tokenized.hpp @@ -0,0 +1,137 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP +#define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP + +#include +#include + +namespace boost +{ + namespace range_detail + { + + template< class R > + struct tokenized_range : + public boost::iterator_range< + boost::regex_token_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + { + private: + typedef + boost::regex_token_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + regex_iter; + + typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type + regex_type; + + typedef boost::iterator_range + base; + + public: + template< class Regex, class Submatch, class Flag > + tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f ) + : base( regex_iter( boost::begin(r), boost::end(r), + regex_type(re), sub, f ), + regex_iter() ) + { } + }; + + template< class T, class U, class V > + struct regex_holder + { + T re; + U sub; + V f; + + regex_holder( const T& rex, const U& subm, V flag ) : + re(rex), sub(subm), f(flag) + { } + private: + // Not assignable + void operator=(const regex_holder&); + }; + + struct regex_forwarder + { + template< class Regex > + regex_holder + operator()( const Regex& re, + int submatch = 0, + regex_constants::match_flag_type f = + regex_constants::match_default ) const + { + return regex_holder( re, submatch, f ); + } + + template< class Regex, class Submatch > + regex_holder + operator()( const Regex& re, + const Submatch& sub, + regex_constants::match_flag_type f = + regex_constants::match_default ) const + { + return regex_holder( re, sub, f ); + } + }; + + template< class BidirectionalRng, class R, class S, class F > + inline tokenized_range + operator|( BidirectionalRng& r, + const regex_holder& f ) + { + return tokenized_range( r, f.re, f.sub, f.f ); + } + + template< class BidirectionalRng, class R, class S, class F > + inline tokenized_range + operator|( const BidirectionalRng& r, + const regex_holder& f ) + { + return tokenized_range( r, f.re, f.sub, f.f ); + } + + } // 'range_detail' + + using range_detail::tokenized_range; + + namespace adaptors + { + namespace + { + const range_detail::regex_forwarder tokenized = + range_detail::regex_forwarder(); + } + + template + inline tokenized_range + tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f) + { + return tokenized_range(rng, reg, sub, f); + } + + template + inline tokenized_range + tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f) + { + return tokenized_range(rng, reg, sub, f); + } + } // 'adaptors' + +} + +#endif diff --git a/boost/range/adaptor/transformed.hpp b/boost/range/adaptor/transformed.hpp new file mode 100644 index 0000000..428ff4b --- /dev/null +++ b/boost/range/adaptor/transformed.hpp @@ -0,0 +1,137 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP +#define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // A type generator to produce the transform_iterator type conditionally + // including a wrapped predicate as appropriate. + template + struct transform_iterator_gen + { + typedef transform_iterator< + typename default_constructible_unary_fn_gen< + P, + typename transform_iterator::reference + >::type, + It + > type; + }; + + template< class F, class R > + struct transformed_range : + public boost::iterator_range< + typename transform_iterator_gen< + F, typename range_iterator::type>::type> + { + private: + typedef typename transform_iterator_gen< + F, typename range_iterator::type>::type transform_iter_t; + + typedef boost::iterator_range base; + + public: + typedef typename default_constructible_unary_fn_gen< + F, + typename transform_iterator< + F, + typename range_iterator::type + >::reference + >::type transform_fn_type; + + typedef R source_range_type; + + transformed_range(transform_fn_type f, R& r) + : base(transform_iter_t(boost::begin(r), f), + transform_iter_t(boost::end(r), f)) + { + } + }; + + template< class T > + struct transform_holder : holder + { + transform_holder( T r ) : holder(r) + { + } + }; + + template< class SinglePassRange, class UnaryFunction > + inline transformed_range + operator|( SinglePassRange& r, + const transform_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return transformed_range( f.val, r ); + } + + template< class SinglePassRange, class UnaryFunction > + inline transformed_range + operator|( const SinglePassRange& r, + const transform_holder& f ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return transformed_range( + f.val, r); + } + + } // 'range_detail' + + using range_detail::transformed_range; + + namespace adaptors + { + namespace + { + const range_detail::forwarder + transformed = + range_detail::forwarder(); + } + + template + inline transformed_range + transform(SinglePassRange& rng, UnaryFunction fn) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return transformed_range(fn, rng); + } + + template + inline transformed_range + transform(const SinglePassRange& rng, UnaryFunction fn) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return transformed_range( + fn, rng); + } + } // 'adaptors' + +} + +#endif diff --git a/boost/range/adaptor/type_erased.hpp b/boost/range/adaptor/type_erased.hpp new file mode 100644 index 0000000..ba5b159 --- /dev/null +++ b/boost/range/adaptor/type_erased.hpp @@ -0,0 +1,196 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED +#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace adaptors + { + template< + class Value = use_default + , class Traversal = use_default + , class Reference = use_default + , class Difference = use_default + , class Buffer = use_default + > + struct type_erased + { + }; + + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + operator|(SinglePassRange& rng, + type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + >) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + typedef typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + return range_type(boost::begin(rng), boost::end(rng)); + } + + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + operator|(const SinglePassRange& rng, + type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + >) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + typedef typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + return range_type(boost::begin(rng), boost::end(rng)); + } + + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + type_erase(SinglePassRange& rng + , type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + > = type_erased<>() + ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + typedef typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + + return range_type(boost::begin(rng), boost::end(rng)); + } + + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + type_erase(const SinglePassRange& rng + , type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + > = type_erased<>() + ) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + typedef typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + + return range_type(boost::begin(rng), boost::end(rng)); + } + } +} // namespace boost + +#endif // include guard diff --git a/boost/range/adaptor/uniqued.hpp b/boost/range/adaptor/uniqued.hpp new file mode 100644 index 0000000..29101d3 --- /dev/null +++ b/boost/range/adaptor/uniqued.hpp @@ -0,0 +1,97 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP +#define BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP + +#include +#include + +namespace boost +{ + + namespace range_detail + { + struct unique_forwarder { }; + + struct unique_not_equal_to + { + typedef bool result_type; + + template< class T > + bool operator()( const T& l, const T& r ) const + { + return !(l == r); + } + }; + + template + class uniqued_range : public adjacent_filtered_range + { + typedef adjacent_filtered_range base; + public: + explicit uniqued_range(ForwardRng& rng) + : base(unique_not_equal_to(), rng) + { + } + }; + + template< class ForwardRng > + inline uniqued_range + operator|( ForwardRng& r, + unique_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return uniqued_range(r); + } + + template< class ForwardRng > + inline uniqued_range + operator|( const ForwardRng& r, + unique_forwarder ) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return uniqued_range(r); + } + + } // 'range_detail' + + using range_detail::uniqued_range; + + namespace adaptors + { + namespace + { + const range_detail::unique_forwarder uniqued = + range_detail::unique_forwarder(); + } + + template + inline uniqued_range + unique(ForwardRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return uniqued_range(rng); + } + + template + inline uniqued_range + unique(const ForwardRange& rng) + { + BOOST_RANGE_CONCEPT_ASSERT(( + ForwardRangeConcept)); + + return uniqued_range(rng); + } + } // 'adaptors' + +} + +#endif diff --git a/boost/range/adaptors.hpp b/boost/range/adaptors.hpp new file mode 100644 index 0000000..0530c4d --- /dev/null +++ b/boost/range/adaptors.hpp @@ -0,0 +1,31 @@ +// Boost.Range library +// +// Copyright Neil Groves 2007. +// Copyright Thorsten Ottosen 2006. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTORS_HPP +#define BOOST_RANGE_ADAPTORS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/boost/range/algorithm.hpp b/boost/range/algorithm.hpp new file mode 100644 index 0000000..30dc583 --- /dev/null +++ b/boost/range/algorithm.hpp @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file algorithm.hpp +/// Includes the range-based versions of the algorithms in the +/// C++ standard header file +// +///////////////////////////////////////////////////////////////////////////// + +// Copyright 2009 Neil Groves. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Acknowledgements: +// This code uses combinations of ideas, techniques and code snippets +// from: Thorsten Ottosen, Eric Niebler, Jeremy Siek, +// and Vladimir Prus' +// +// The original mutating algorithms that served as the first version +// were originally written by Vladimir Prus' +// code from Boost Wiki + +#if defined(_MSC_VER) +#pragma once +#endif + +#ifndef BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009 +#define BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009 + +#include +#include +#include +#include +#include +#include +#include + +// Non-mutating algorithms +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Mutating algorithms +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Binary search +#include +#include +#include +#include + +// Set operations of sorted ranges +#include + +// Heap operations +#include + +// Minimum and Maximum +#include +#include + +// Permutations +#include + +#endif // include guard + diff --git a/boost/range/algorithm/adjacent_find.hpp b/boost/range/algorithm/adjacent_find.hpp new file mode 100644 index 0000000..1b88dae --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include + +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::type +adjacent_find(ForwardRange & rng) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return std::adjacent_find(boost::begin(rng),boost::end(rng)); +} + +/// \overload +template< typename ForwardRange > +inline typename range_iterator::type +adjacent_find(const ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return std::adjacent_find(boost::begin(rng),boost::end(rng)); +} + +/// \overload +template< typename ForwardRange, typename BinaryPredicate > +inline typename range_iterator::type +adjacent_find(ForwardRange & rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + typename range_value::type>)); + return std::adjacent_find(boost::begin(rng),boost::end(rng),pred); +} + +/// \overload +template< typename ForwardRange, typename BinaryPredicate > +inline typename range_iterator::type +adjacent_find(const ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + typename range_value::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::type +adjacent_find(ForwardRange & rng) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return range_return:: + pack(std::adjacent_find(boost::begin(rng),boost::end(rng)), + rng); +} + +/// \overload +template< range_return_value re, typename ForwardRange > +inline typename range_return::type +adjacent_find(const ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return range_return:: + 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::type +adjacent_find(ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + typename range_value::type>)); + return range_return:: + 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::type +adjacent_find(const ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return range_return:: + 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/boost/range/algorithm/binary_search.hpp b/boost/range/algorithm/binary_search.hpp new file mode 100644 index 0000000..bb64ec8 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline bool binary_search(const ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::binary_search(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template +inline bool binary_search(const ForwardRange& rng, const Value& val, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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/boost/range/algorithm/copy.hpp b/boost/range/algorithm/copy.hpp new file mode 100644 index 0000000..f15b31f --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 )); + return std::copy(boost::begin(rng),boost::end(rng),out); +} + + } // namespace range + using range::copy; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/copy_backward.hpp b/boost/range/algorithm/copy_backward.hpp new file mode 100644 index 0000000..c95c6f1 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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/boost/range/algorithm/count.hpp b/boost/range/algorithm/count.hpp new file mode 100644 index 0000000..8316ce0 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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::type +count(SinglePassRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::count(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template< class SinglePassRange, class Value > +inline BOOST_DEDUCED_TYPENAME range_difference::type +count(const SinglePassRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::count(boost::begin(rng), boost::end(rng), val); +} + + } // namespace range + using range::count; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/count_if.hpp b/boost/range/algorithm/count_if.hpp new file mode 100644 index 0000000..ae17b0e --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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::type +count_if(SinglePassRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::count_if(boost::begin(rng), boost::end(rng), pred); +} + +/// \overload +template< class SinglePassRange, class UnaryPredicate > +inline BOOST_DEDUCED_TYPENAME boost::range_difference::type +count_if(const SinglePassRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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/boost/range/algorithm/equal.hpp b/boost/range/algorithm/equal.hpp new file mode 100644 index 0000000..2b44f3b --- /dev/null +++ b/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 +#include +#include + +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 )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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 )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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/boost/range/algorithm/equal_range.hpp b/boost/range/algorithm/equal_range.hpp new file mode 100644 index 0000000..4aa4a54 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline std::pair< + BOOST_DEDUCED_TYPENAME boost::range_iterator::type, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + > +equal_range(ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::equal_range(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template +inline std::pair< + BOOST_DEDUCED_TYPENAME boost::range_iterator::type, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + > +equal_range(const ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::equal_range(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template +inline std::pair< + BOOST_DEDUCED_TYPENAME boost::range_iterator::type, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + > +equal_range(ForwardRange& rng, const Value& val, SortPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::equal_range(boost::begin(rng), boost::end(rng), val, pred); +} + +/// \overload +template +inline std::pair< + BOOST_DEDUCED_TYPENAME boost::range_iterator::type, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + > +equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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/boost/range/algorithm/fill.hpp b/boost/range/algorithm/fill.hpp new file mode 100644 index 0000000..95231a8 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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 )); + std::fill(boost::begin(rng), boost::end(rng), val); + return rng; +} + + } // namespace range + using range::fill; +} + +#endif // include guard diff --git a/boost/range/algorithm/fill_n.hpp b/boost/range/algorithm/fill_n.hpp new file mode 100644 index 0000000..02a0c2a --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 )); + BOOST_ASSERT( static_cast(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 )); + BOOST_ASSERT( static_cast(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/boost/range/algorithm/find.hpp b/boost/range/algorithm/find.hpp new file mode 100644 index 0000000..72c5cf1 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +find( SinglePassRange& rng, const Value& val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::find(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template< class SinglePassRange, class Value > +inline BOOST_DEDUCED_TYPENAME range_iterator::type +find( const SinglePassRange& rng, const Value& val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +find( SinglePassRange& rng, const Value& val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return range_return:: + 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::type +find( const SinglePassRange& rng, const Value& val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return range_return:: + pack(std::find(boost::begin(rng), boost::end(rng), val), + rng); +} + + } // namespace range + using range::find; +} + +#endif // include guard diff --git a/boost/range/algorithm/find_end.hpp b/boost/range/algorithm/find_end.hpp new file mode 100644 index 0000000..757e999 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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, + BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type +>::type +find_end(ForwardRange1 & rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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 )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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::type +find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +find_end(ForwardRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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::type +find_end(const ForwardRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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::type +find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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/boost/range/algorithm/find_first_of.hpp b/boost/range/algorithm/find_first_of.hpp new file mode 100644 index 0000000..4cb5989 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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::type +find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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::type +find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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::type +find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +find_first_of(SinglePassRange1 & rng1, const ForwardRange2& rng2, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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::type +find_first_of(const SinglePassRange1 & rng1, const ForwardRange2& rng2, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + + return range_return:: + 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/boost/range/algorithm/find_if.hpp b/boost/range/algorithm/find_if.hpp new file mode 100644 index 0000000..2d1926d --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +find_if( SinglePassRange& rng, UnaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::find_if(boost::begin(rng), boost::end(rng), pred); +} + +/// \overload +template< class SinglePassRange, class UnaryPredicate > +inline BOOST_DEDUCED_TYPENAME range_iterator::type +find_if( const SinglePassRange& rng, UnaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +find_if( SinglePassRange& rng, UnaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return range_return:: + 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::type +find_if( const SinglePassRange& rng, UnaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return range_return:: + 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/boost/range/algorithm/for_each.hpp b/boost/range/algorithm/for_each.hpp new file mode 100644 index 0000000..ea731b2 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) +#include +#endif + +namespace boost +{ + namespace range + { + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + namespace for_each_detail + { + template + inline UnaryFunction + for_each_impl(Iterator first, Iterator last, UnaryFunction fun, + typename ::boost::enable_if< + is_reference_wrapper, + void + >::type* = 0) + { + typedef typename std::_Get_unchecked_type::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 + inline UnaryFunction + for_each_impl(Iterator first, Iterator last, UnaryFunction fn, + typename disable_if< + is_reference_wrapper, + void + >::type* = 0) + { + return std::for_each(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 )); + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + return for_each_detail::for_each_impl< + typename range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#else + return std::for_each< + BOOST_DEDUCED_TYPENAME range_iterator::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 )); + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + return for_each_detail::for_each_impl< + typename range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#else + return std::for_each< + BOOST_DEDUCED_TYPENAME range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#endif +} + + } // namespace range + using range::for_each; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/generate.hpp b/boost/range/algorithm/generate.hpp new file mode 100644 index 0000000..324412c --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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 )); + std::generate(boost::begin(rng), boost::end(rng), gen); + return rng; +} + + } // namespace range + using range::generate; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/heap_algorithm.hpp b/boost/range/algorithm/heap_algorithm.hpp new file mode 100644 index 0000000..584920d --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline RandomAccessRange& push_heap(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::push_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& push_heap(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::push_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& push_heap(RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::push_heap(boost::begin(rng), boost::end(rng), comp_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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 +inline RandomAccessRange& pop_heap(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::pop_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::pop_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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 +inline RandomAccessRange& make_heap(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::make_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& make_heap(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::make_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& make_heap(RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::make_heap(boost::begin(rng), boost::end(rng), comp_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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 +inline RandomAccessRange& sort_heap(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort_heap(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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/boost/range/algorithm/inplace_merge.hpp b/boost/range/algorithm/inplace_merge.hpp new file mode 100644 index 0000000..dfadbaa --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline BidirectionalRange& inplace_merge(BidirectionalRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + std::inplace_merge(boost::begin(rng), middle, boost::end(rng)); + return rng; +} + +/// \overload +template +inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type middle) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + std::inplace_merge(boost::begin(rng), middle, boost::end(rng)); + return rng; +} + +/// \overload +template +inline BidirectionalRange& inplace_merge(BidirectionalRange& rng, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type middle, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred); + return rng; +} + +/// \overload +template +inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng, + BOOST_DEDUCED_TYPENAME boost::range_iterator::type middle, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + 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/boost/range/algorithm/lexicographical_compare.hpp b/boost/range/algorithm/lexicographical_compare.hpp new file mode 100644 index 0000000..c6e4bc8 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline bool lexicographical_compare(const SinglePassRange1& rng1, + const SinglePassRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::lexicographical_compare( + boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2)); +} + +/// \overload +template +inline bool lexicographical_compare(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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/boost/range/algorithm/lower_bound.hpp b/boost/range/algorithm/lower_bound.hpp new file mode 100644 index 0000000..cb5e639 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +lower_bound( ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::lower_bound(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template< class ForwardRange, class Value > +inline BOOST_DEDUCED_TYPENAME range_iterator::type +lower_bound( const ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +lower_bound( ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +lower_bound( const ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +lower_bound( ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +lower_bound( const ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +lower_bound( ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +lower_bound( const ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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/boost/range/algorithm/max_element.hpp b/boost/range/algorithm/max_element.hpp new file mode 100644 index 0000000..a0c1ffd --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline BOOST_DEDUCED_TYPENAME range_iterator::type +max_element(ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::max_element(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +max_element(const ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::max_element(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +max_element(ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::max_element(boost::begin(rng), boost::end(rng), pred); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +max_element(const ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::max_element(boost::begin(rng), boost::end(rng), pred); +} + +// range_return overloads + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +max_element(ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::max_element(boost::begin(rng), boost::end(rng)), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +max_element(const ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::max_element(boost::begin(rng), boost::end(rng)), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +max_element(ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::max_element(boost::begin(rng), boost::end(rng), pred), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +max_element(const ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::max_element(boost::begin(rng), boost::end(rng), pred), + rng); +} + + } // namespace range + using range::max_element; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/merge.hpp b/boost/range/algorithm/merge.hpp new file mode 100644 index 0000000..c81b8c7 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline OutputIterator merge(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::merge(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2), out); +} + +/// \overload +template +inline OutputIterator merge(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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/boost/range/algorithm/min_element.hpp b/boost/range/algorithm/min_element.hpp new file mode 100644 index 0000000..c966b1e --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline BOOST_DEDUCED_TYPENAME range_iterator::type +min_element(ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::min_element(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +min_element(const ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::min_element(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +min_element(ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::min_element(boost::begin(rng), boost::end(rng), pred); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +min_element(const ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::min_element(boost::begin(rng), boost::end(rng), pred); +} + +// range_return overloads + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +min_element(ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::min_element(boost::begin(rng), boost::end(rng)), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +min_element(const ForwardRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::min_element(boost::begin(rng), boost::end(rng)), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +min_element(ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::min_element(boost::begin(rng), boost::end(rng), pred), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +min_element(const ForwardRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::min_element(boost::begin(rng), boost::end(rng), pred), + rng); +} + + } // namespace range + using range::min_element; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/mismatch.hpp b/boost/range/algorithm/mismatch.hpp new file mode 100644 index 0000000..2819c33 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< class SinglePassTraversalReadableIterator1, + class SinglePassTraversalReadableIterator2 > + inline std::pair + mismatch_impl(SinglePassTraversalReadableIterator1 first1, + SinglePassTraversalReadableIterator1 last1, + SinglePassTraversalReadableIterator2 first2, + SinglePassTraversalReadableIterator2 last2) + { + while (first1 != last1 && first2 != last2 && *first1 == *first2) + { + ++first1; + ++first2; + } + return std::pair(first1, first2); + } + + template< class SinglePassTraversalReadableIterator1, + class SinglePassTraversalReadableIterator2, + class BinaryPredicate > + inline std::pair + 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(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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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::type, + BOOST_DEDUCED_TYPENAME range_iterator::type > +mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + 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/boost/range/algorithm/nth_element.hpp b/boost/range/algorithm/nth_element.hpp new file mode 100644 index 0000000..a605595 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline RandomAccessRange& nth_element(RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type nth) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::nth_element(boost::begin(rng), nth, boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& nth_element(const RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type nth) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::nth_element(boost::begin(rng), nth, boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& nth_element(RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type nth, + BinaryPredicate sort_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& nth_element(const RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type nth, + BinaryPredicate sort_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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/boost/range/algorithm/partial_sort.hpp b/boost/range/algorithm/partial_sort.hpp new file mode 100644 index 0000000..d7044cd --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline RandomAccessRange& partial_sort(RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::partial_sort(boost::begin(rng), middle, boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::partial_sort(boost::begin(rng), middle, boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& partial_sort(RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle, + BinaryPredicate sort_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::partial_sort(boost::begin(rng), middle, boost::end(rng), + sort_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle, + BinaryPredicate sort_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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/boost/range/algorithm/partial_sort_copy.hpp b/boost/range/algorithm/partial_sort_copy.hpp new file mode 100644 index 0000000..9129389 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline BOOST_DEDUCED_TYPENAME range_iterator::type +partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2)); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2)); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2), pred); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + 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/boost/range/algorithm/partition.hpp b/boost/range/algorithm/partition.hpp new file mode 100644 index 0000000..b814a24 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline BOOST_DEDUCED_TYPENAME range_iterator::type +partition(ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::partition(boost::begin(rng),boost::end(rng),pred); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +partition(const ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +partition(ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return boost::range_return:: + 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::type +partition(const ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return boost::range_return:: + pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng); +} + + } // namespace range + using range::partition; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/permutation.hpp b/boost/range/algorithm/permutation.hpp new file mode 100644 index 0000000..75388cc --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline bool next_permutation(BidirectionalRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::next_permutation(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline bool next_permutation(const BidirectionalRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::next_permutation(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline bool next_permutation(BidirectionalRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::next_permutation(boost::begin(rng), boost::end(rng), + comp_pred); +} + +/// \overload +template +inline bool next_permutation(const BidirectionalRange& rng, + Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + 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 +inline bool prev_permutation(BidirectionalRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::prev_permutation(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline bool prev_permutation(const BidirectionalRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::prev_permutation(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline bool prev_permutation(BidirectionalRange& rng, Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::prev_permutation(boost::begin(rng), boost::end(rng), + comp_pred); +} + +/// \overload +template +inline bool prev_permutation(const BidirectionalRange& rng, + Compare comp_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + 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/boost/range/algorithm/random_shuffle.hpp b/boost/range/algorithm/random_shuffle.hpp new file mode 100644 index 0000000..95bbd97 --- /dev/null +++ b/boost/range/algorithm/random_shuffle.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_RANDOM_SHUFFLE_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +/// \brief template function random_shuffle +/// +/// range-based version of the random_shuffle std algorithm +/// +/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept +/// \pre Generator is a model of the UnaryFunctionConcept +template +inline RandomAccessRange& random_shuffle(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::random_shuffle(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::random_shuffle(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::random_shuffle(boost::begin(rng), boost::end(rng), gen); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::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/boost/range/algorithm/remove.hpp b/boost/range/algorithm/remove.hpp new file mode 100644 index 0000000..699a7cd --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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::type +remove(ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::remove(boost::begin(rng),boost::end(rng),val); +} + +/// \overload +template< class ForwardRange, class Value > +inline BOOST_DEDUCED_TYPENAME range_iterator::type +remove(const ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +remove(ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::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::type +remove(const ForwardRange& rng, const Value& val) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::pack( + std::remove(boost::begin(rng), boost::end(rng), val), + rng); +} + + } // namespace range + using range::remove; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/remove_copy.hpp b/boost/range/algorithm/remove_copy.hpp new file mode 100644 index 0000000..b65747e --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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/boost/range/algorithm/remove_copy_if.hpp b/boost/range/algorithm/remove_copy_if.hpp new file mode 100644 index 0000000..8d9c37b --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + return std::remove_copy_if(boost::begin(rng), boost::end(rng), out_it, pred); + } +} + +#endif // include guard diff --git a/boost/range/algorithm/remove_if.hpp b/boost/range/algorithm/remove_if.hpp new file mode 100644 index 0000000..a965df0 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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::type +remove_if(ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::remove_if(boost::begin(rng), boost::end(rng), pred); +} + +/// \overload +template< class ForwardRange, class UnaryPredicate > +inline BOOST_DEDUCED_TYPENAME boost::range_iterator::type +remove_if(const ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +remove_if(ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::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::type +remove_if(const ForwardRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return::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/boost/range/algorithm/replace.hpp b/boost/range/algorithm/replace.hpp new file mode 100644 index 0000000..44d3e4c --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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 )); + 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/boost/range/algorithm/replace_copy.hpp b/boost/range/algorithm/replace_copy.hpp new file mode 100644 index 0000000..0c02005 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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/boost/range/algorithm/replace_copy_if.hpp b/boost/range/algorithm/replace_copy_if.hpp new file mode 100644 index 0000000..d313151 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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/boost/range/algorithm/replace_if.hpp b/boost/range/algorithm/replace_if.hpp new file mode 100644 index 0000000..93d5a1f --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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 )); + 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/boost/range/algorithm/reverse.hpp b/boost/range/algorithm/reverse.hpp new file mode 100644 index 0000000..20a7eb1 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline BidirectionalRange& reverse(BidirectionalRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + std::reverse(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const BidirectionalRange& reverse(const BidirectionalRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + std::reverse(boost::begin(rng), boost::end(rng)); + return rng; +} + + } // namespace range + using range::reverse; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/reverse_copy.hpp b/boost/range/algorithm/reverse_copy.hpp new file mode 100644 index 0000000..f1990ad --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + 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/boost/range/algorithm/rotate.hpp b/boost/range/algorithm/rotate.hpp new file mode 100644 index 0000000..ca4b223 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline ForwardRange& rotate(ForwardRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + std::rotate(boost::begin(rng), middle, boost::end(rng)); + return rng; +} + +/// \overload +template +inline const ForwardRange& rotate(const ForwardRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + std::rotate(boost::begin(rng), middle, boost::end(rng)); + return rng; +} + + } // namespace range + using range::rotate; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/rotate_copy.hpp b/boost/range/algorithm/rotate_copy.hpp new file mode 100644 index 0000000..0409ac5 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 + inline OutputIterator rotate_copy( + const ForwardRange& rng, + BOOST_DEDUCED_TYPENAME range_iterator::type middle, + OutputIterator target + ) + { + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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/boost/range/algorithm/search.hpp b/boost/range/algorithm/search.hpp new file mode 100644 index 0000000..28cc6e6 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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::type +search(ForwardRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +search(const ForwardRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +search(ForwardRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +search(const ForwardRange1& rng1, const ForwardRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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/boost/range/algorithm/search_n.hpp b/boost/range/algorithm/search_n.hpp new file mode 100644 index 0000000..ccfb27a --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include + +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 + 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::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 + inline RandomAccessIterator + search_n_impl(RandomAccessIterator first, RandomAccessIterator last, + Integer count, const Value& value, + std::random_access_iterator_tag) + { + typedef typename std::iterator_traits::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 + 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::difference_type difference_t; + + while (first != last && !static_cast(pred(*first, value))) + ++first; + + while (first != last) + { + difference_t n = count; + ForwardIterator i = first; + ++i; + while (i != last && n != 1 && static_cast(pred(*i, value))) + { + ++i; + --n; + } + if (n == 1) + return first; + if (i == last) + return last; + first = ++i; + while (first != last && !static_cast(pred(*first, value))) + ++first; + } + return last; + } + + // search_n for random-access iterators using a binary predicate + // to determine a match + template + 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::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(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 + inline ForwardIterator + search_n_impl(ForwardIterator first, ForwardIterator last, + Integer count, const Value& value) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept)); + BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept)); + BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept::value_type>)); + //BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2::value_type, Value>)); + + typedef typename std::iterator_traits::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 + inline ForwardIterator + search_n_pred_impl(ForwardIterator first, ForwardIterator last, + Integer count, const Value& value, + BinaryPredicate pred) + { + BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + BinaryPredicateConcept< + BinaryPredicate, + typename std::iterator_traits::value_type, + Value> + )); + + typedef typename std::iterator_traits::iterator_category cat_t; + + if (count <= 0) + return first; + if (count == 1) + { + while (first != last && !static_cast(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::type +search_n(ForwardRange& rng, Integer count, const Value& value) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + 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::type +search_n(const ForwardRange& rng, Integer count, const Value& value) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + 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::type +search_n(ForwardRange& rng, Integer count, const Value& value, + BinaryPredicate binary_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::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::type +search_n(const ForwardRange& rng, Integer count, const Value& value, + BinaryPredicate binary_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::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::type +search_n(ForwardRange& rng, Integer count, const Value& value) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return range_return:: + 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::type +search_n(const ForwardRange& rng, Integer count, const Value& value) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + return range_return:: + 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::type +search_n(ForwardRange& rng, Integer count, const Value& value, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + const Value&>)); + return range_return:: + 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::type +search_n(const ForwardRange& rng, Integer count, const Value& value, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + const Value&>)); + return range_return:: + 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/boost/range/algorithm/set_algorithm.hpp b/boost/range/algorithm/set_algorithm.hpp new file mode 100644 index 0000000..82ef8ec --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline bool includes(const SinglePassRange1& rng1, + const SinglePassRange2& rng2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::includes(boost::begin(rng1),boost::end(rng1), + boost::begin(rng2),boost::end(rng2)); +} + +/// \overload +template +inline bool includes(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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 +inline OutputIterator set_union(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::set_union(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2), out); +} + +/// \overload +template +inline OutputIterator set_union(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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 +inline OutputIterator set_intersection(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::set_intersection(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2), out); +} + +/// \overload +template +inline OutputIterator set_intersection(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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 +inline OutputIterator set_difference(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::set_difference(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2), out); +} + +/// \overload +template +inline OutputIterator set_difference(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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 +inline OutputIterator +set_symmetric_difference(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), boost::end(rng2), out); +} + +/// \overload +template +inline OutputIterator +set_symmetric_difference(const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + OutputIterator out, + BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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/boost/range/algorithm/sort.hpp b/boost/range/algorithm/sort.hpp new file mode 100644 index 0000000..45eecde --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline RandomAccessRange& sort(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& sort(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort(boost::begin(rng), boost::end(rng), pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::sort(boost::begin(rng), boost::end(rng), pred); + return rng; +} + + } // namespace range + using range::sort; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/stable_partition.hpp b/boost/range/algorithm/stable_partition.hpp new file mode 100644 index 0000000..24febfc --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 +inline BOOST_DEDUCED_TYPENAME range_iterator::type +stable_partition(BidirectionalRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::stable_partition(boost::begin(rng), boost::end(rng), pred); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_iterator::type +stable_partition(const BidirectionalRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return std::stable_partition(boost::begin(rng),boost::end(rng),pred); +} + +// range_return overloads +template +inline BOOST_DEDUCED_TYPENAME range_return::type +stable_partition(BidirectionalRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return range_return::pack( + std::stable_partition(boost::begin(rng), boost::end(rng), pred), + rng); +} + +/// \overload +template +inline BOOST_DEDUCED_TYPENAME range_return::type +stable_partition(const BidirectionalRange& rng, UnaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept )); + return range_return::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/boost/range/algorithm/stable_sort.hpp b/boost/range/algorithm/stable_sort.hpp new file mode 100644 index 0000000..d18da4d --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 +inline RandomAccessRange& stable_sort(RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::stable_sort(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::stable_sort(boost::begin(rng), boost::end(rng)); + return rng; +} + +/// \overload +template +inline RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate sort_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred); + return rng; +} + +/// \overload +template +inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate sort_pred) +{ + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept )); + 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/boost/range/algorithm/swap_ranges.hpp b/boost/range/algorithm/swap_ranges.hpp new file mode 100644 index 0000000..52b0162 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template + 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 + 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 + void swap_ranges_impl(Iterator1 first1, Iterator1 last1, + Iterator2 first2, Iterator2 last2) + { + swap_ranges_impl(first1, last1, first2, last2, + BOOST_DEDUCED_TYPENAME iterator_traversal::type(), + BOOST_DEDUCED_TYPENAME iterator_traversal::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)); + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + 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)); + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + 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)); + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + 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)); + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + + 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/boost/range/algorithm/transform.hpp b/boost/range/algorithm/transform.hpp new file mode 100644 index 0000000..ade147a --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 )); + 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 )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + 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/boost/range/algorithm/unique.hpp b/boost/range/algorithm/unique.hpp new file mode 100644 index 0000000..8017a83 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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::type +unique( ForwardRange& rng ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + pack( std::unique( boost::begin(rng), + boost::end(rng)), rng ); +} + +/// \overload +template< range_return_value re, class ForwardRange > +inline BOOST_DEDUCED_TYPENAME range_return::type +unique( const ForwardRange& rng ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +unique( ForwardRange& rng, BinaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +unique( const ForwardRange& rng, BinaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + pack(std::unique(boost::begin(rng), boost::end(rng), pred), + rng); +} + +/// \overload +template< class ForwardRange > +inline BOOST_DEDUCED_TYPENAME range_return::type +unique( ForwardRange& rng ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return ::boost::range::unique(rng); +} +/// \overload +template< class ForwardRange > +inline BOOST_DEDUCED_TYPENAME range_return::type +unique( const ForwardRange& rng ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return ::boost::range::unique(rng); +} +/// \overload +template< class ForwardRange, class BinaryPredicate > +inline BOOST_DEDUCED_TYPENAME range_return::type +unique( ForwardRange& rng, BinaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return ::boost::range::unique(rng, pred); +} +/// \overload +template< class ForwardRange, class BinaryPredicate > +inline BOOST_DEDUCED_TYPENAME range_return::type +unique( const ForwardRange& rng, BinaryPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return ::boost::range::unique(rng, pred); +} + + } // namespace range + using range::unique; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm/unique_copy.hpp b/boost/range/algorithm/unique_copy.hpp new file mode 100644 index 0000000..0682d74 --- /dev/null +++ b/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 +#include +#include +#include +#include + +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 )); + 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 )); + 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/boost/range/algorithm/upper_bound.hpp b/boost/range/algorithm/upper_bound.hpp new file mode 100644 index 0000000..c8acbc6 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +upper_bound( ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return std::upper_bound(boost::begin(rng), boost::end(rng), val); +} + +/// \overload +template< class ForwardRange, class Value > +BOOST_DEDUCED_TYPENAME range_iterator::type +upper_bound( const ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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, + BOOST_DEDUCED_TYPENAME range_iterator::type +>::type +upper_bound( ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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::type +upper_bound( const ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +upper_bound( ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +upper_bound( const ForwardRange& rng, Value val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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, + BOOST_DEDUCED_TYPENAME range_return::type +>::type +upper_bound( ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + 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::type +upper_bound( const ForwardRange& rng, Value val, SortPredicate pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + return range_return:: + pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred), + rng); +} + + } // namespace range + using range::upper_bound; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext.hpp b/boost/range/algorithm_ext.hpp new file mode 100644 index 0000000..783d38a --- /dev/null +++ b/boost/range/algorithm_ext.hpp @@ -0,0 +1,28 @@ +// Boost.Range library +// +// Copyright Neil Groves 2007. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Copyright Thorsten Ottosen 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_HPP +#define BOOST_RANGE_ALGORITHM_EXT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/boost/range/algorithm_ext/copy_n.hpp b/boost/range/algorithm_ext/copy_n.hpp new file mode 100644 index 0000000..f855441 --- /dev/null +++ b/boost/range/algorithm_ext/copy_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_COPY_N_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +/// \brief template function copy +/// +/// range-based version of the copy std algorithm +/// +/// \pre SinglePassRange is a model of the SinglePassRangeConcept +/// \pre OutputIterator is a model of the OutputIteratorConcept +/// \pre 0 <= n <= distance(rng) +template< class SinglePassRange, class Size, class OutputIterator > +inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_ASSERT( n <= static_cast(::boost::distance(rng)) ); + BOOST_ASSERT( n >= static_cast(0) ); + + BOOST_DEDUCED_TYPENAME range_iterator::type source = ::boost::begin(rng); + + for (Size i = 0; i < n; ++i, ++out, ++source) + *out = *source; + + return out; +} + + } // namespace range + using ::boost::range::copy_n; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/erase.hpp b/boost/range/algorithm_ext/erase.hpp new file mode 100644 index 0000000..107d32b --- /dev/null +++ b/boost/range/algorithm_ext/erase.hpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +template< class Container > +inline Container& erase( Container& on, + iterator_range to_erase ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + on.erase( boost::begin(to_erase), boost::end(to_erase) ); + return on; +} + +template< class Container, class T > +inline Container& remove_erase( Container& on, const T& val ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + on.erase( + std::remove(boost::begin(on), boost::end(on), val), + boost::end(on)); + return on; +} + +template< class Container, class Pred > +inline Container& remove_erase_if( Container& on, Pred pred ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + on.erase( + std::remove_if(boost::begin(on), boost::end(on), pred), + boost::end(on)); + return on; +} + + } // namespace range + using range::erase; + using range::remove_erase; + using range::remove_erase_if; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/for_each.hpp b/boost/range/algorithm_ext/for_each.hpp new file mode 100644 index 0000000..a470e2b --- /dev/null +++ b/boost/range/algorithm_ext/for_each.hpp @@ -0,0 +1,86 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template + inline Fn2 for_each_impl(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Fn2 fn) + { + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + { + fn(*first1, *first2); + } + return fn; + } + } + + namespace range + { + template + inline Fn2 for_each(const SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn) + { + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + return ::boost::range_detail::for_each_impl( + ::boost::begin(rng1), ::boost::end(rng1), + ::boost::begin(rng2), ::boost::end(rng2), fn); + } + + template + inline Fn2 for_each(const SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn) + { + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + return ::boost::range_detail::for_each_impl( + ::boost::begin(rng1), ::boost::end(rng1), + ::boost::begin(rng2), ::boost::end(rng2), fn); + } + + template + inline Fn2 for_each(SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn) + { + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + return ::boost::range_detail::for_each_impl( + ::boost::begin(rng1), ::boost::end(rng1), + ::boost::begin(rng2), ::boost::end(rng2), fn); + } + + template + inline Fn2 for_each(SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn) + { + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + return ::boost::range_detail::for_each_impl( + ::boost::begin(rng1), ::boost::end(rng1), + ::boost::begin(rng2), ::boost::end(rng2), fn); + } + } // namespace range + using range::for_each; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/insert.hpp b/boost/range/algorithm_ext/insert.hpp new file mode 100644 index 0000000..c0c04c8 --- /dev/null +++ b/boost/range/algorithm_ext/insert.hpp @@ -0,0 +1,48 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +template< class Container, class Range > +inline Container& insert( Container& on, + BOOST_DEDUCED_TYPENAME Container::iterator before, + const Range& from ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + on.insert( before, boost::begin(from), boost::end(from) ); + return on; +} + +template< class Container, class Range > +inline Container& insert( Container& on, const Range& from ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + on.insert(boost::begin(from), boost::end(from)); +} + + } // namespace range + using range::insert; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/iota.hpp b/boost/range/algorithm_ext/iota.hpp new file mode 100644 index 0000000..f7af446 --- /dev/null +++ b/boost/range/algorithm_ext/iota.hpp @@ -0,0 +1,54 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +template< class ForwardRange, class Value > +inline ForwardRange& iota( ForwardRange& rng, Value x ) +{ + BOOST_CONCEPT_ASSERT(( ForwardRangeConcept )); + typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator_t; + + iterator_t last_target = ::boost::end(rng); + for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x) + *target = x; + + return rng; +} + +template< class ForwardRange, class Value > +inline const ForwardRange& iota( const ForwardRange& rng, Value x ) +{ + BOOST_CONCEPT_ASSERT(( ForwardRangeConcept )); + typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator_t; + + iterator_t last_target = ::boost::end(rng); + for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x) + *target = x; + + return rng; +} + + } // namespace range + using range::iota; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/is_sorted.hpp b/boost/range/algorithm_ext/is_sorted.hpp new file mode 100644 index 0000000..3d00729 --- /dev/null +++ b/boost/range/algorithm_ext/is_sorted.hpp @@ -0,0 +1,57 @@ +// Copyright Bryce Lelbach 2010 +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +/// \brief template function is_sorted +/// +/// range-based version of the is_sorted std algorithm +/// +/// \pre SinglePassRange is a model of the SinglePassRangeConcept +template +inline bool is_sorted(const SinglePassRange& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept::type>)); + return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng)); +} + +/// \overload +template +inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred) +{ + BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + BOOST_DEDUCED_TYPENAME range_value::type>)); + return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred); +} + + } // namespace range + +using range::is_sorted; + +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/overwrite.hpp b/boost/range/algorithm_ext/overwrite.hpp new file mode 100644 index 0000000..f84f6ea --- /dev/null +++ b/boost/range/algorithm_ext/overwrite.hpp @@ -0,0 +1,84 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +template< class SinglePassRange1, class SinglePassRange2 > +inline void overwrite( const SinglePassRange1& from, SinglePassRange2& to ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + BOOST_DEDUCED_TYPENAME range_iterator::type + i = boost::begin(from), e = boost::end(from); + + BOOST_DEDUCED_TYPENAME range_iterator::type + out = boost::begin(to); + +#ifndef NDEBUG + BOOST_DEDUCED_TYPENAME range_iterator::type + last_out = boost::end(to); +#endif + + for( ; i != e; ++out, ++i ) + { +#ifndef NDEBUG + BOOST_ASSERT( out != last_out + && "out of bounds in boost::overwrite()" ); +#endif + *out = *i; + } +} + +template< class SinglePassRange1, class SinglePassRange2 > +inline void overwrite( const SinglePassRange1& from, const SinglePassRange2& to ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + BOOST_DEDUCED_TYPENAME range_iterator::type + i = boost::begin(from), e = boost::end(from); + + BOOST_DEDUCED_TYPENAME range_iterator::type + out = boost::begin(to); + +#ifndef NDEBUG + BOOST_DEDUCED_TYPENAME range_iterator::type + last_out = boost::end(to); +#endif + + for( ; i != e; ++out, ++i ) + { +#ifndef NDEBUG + BOOST_ASSERT( out != last_out + && "out of bounds in boost::overwrite()" ); +#endif + *out = *i; + } +} + + } // namespace range + using range::overwrite; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/push_back.hpp b/boost/range/algorithm_ext/push_back.hpp new file mode 100644 index 0000000..6fb9b9b --- /dev/null +++ b/boost/range/algorithm_ext/push_back.hpp @@ -0,0 +1,41 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +template< class Container, class Range > +inline Container& push_back( Container& on, const Range& from ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_ASSERT_MSG(!range_detail::is_same_object(on, from), + "cannot copy from a container to itself"); + on.insert( on.end(), boost::begin(from), boost::end(from) ); + return on; +} + + } // namespace range + using range::push_back; +} // namespace boost + +#endif // include guard diff --git a/boost/range/algorithm_ext/push_front.hpp b/boost/range/algorithm_ext/push_front.hpp new file mode 100644 index 0000000..e893098 --- /dev/null +++ b/boost/range/algorithm_ext/push_front.hpp @@ -0,0 +1,41 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED +#define BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + +template< class Container, class Range > +inline Container& push_front( Container& on, const Range& from ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_ASSERT_MSG(!range_detail::is_same_object(on, from), + "cannot copy from a container to itself"); + on.insert( on.begin(), boost::begin(from), boost::end(from) ); + return on; +} + + } // namespace range + using range::push_front; +} // namespace boost + +#endif // include guard diff --git a/boost/range/any_range.hpp b/boost/range/any_range.hpp new file mode 100644 index 0000000..1cb5996 --- /dev/null +++ b/boost/range/any_range.hpp @@ -0,0 +1,204 @@ +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED +#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // If T is use_default, return the result of Default, otherwise + // return T. + // + // This is an implementation artifact used to pick intelligent default + // values when the user specified boost::use_default as a template + // parameter. + template< + class T, + class Default + > + struct any_range_default_help + : mpl::eval_if< + is_same + , Default + , mpl::identity + > + { + }; + + template< + class WrappedRange + , class Value + , class Reference + > + struct any_range_value_type + { +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + typedef typename any_range_default_help< + Value + , mpl::eval_if< + is_same + , range_value< + typename remove_const + ::type> + , remove_reference + > + >::type type; +# else + typedef typename any_range_default_help< + Value + , range_value< + typename remove_const + ::type> + >::type type; +# endif + }; + + template< + class Value + , class Traversal + , class Reference = Value& + , class Difference = std::ptrdiff_t + , class Buffer = use_default + > + class any_range + : public iterator_range< + any_iterator< + Value + , Traversal + , Reference + , Difference + , typename any_range_default_help< + Buffer + , mpl::identity + >::type + > + > + { + typedef iterator_range< + any_iterator< + Value + , Traversal + , Reference + , Difference + , typename any_range_default_help< + Buffer + , mpl::identity + >::type + > + > base_type; + + struct enabler {}; + struct disabler {}; + public: + any_range() + { + } + + any_range(const any_range& other) + : base_type(other) + { + } + + template + any_range(WrappedRange& wrapped_range) + : base_type(boost::begin(wrapped_range), + boost::end(wrapped_range)) + { + } + + template + any_range(const WrappedRange& wrapped_range) + : base_type(boost::begin(wrapped_range), + boost::end(wrapped_range)) + { + } + + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_range(const any_range< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other) + : base_type(boost::begin(other), boost::end(other)) + { + } + + template + any_range(Iterator first, Iterator last) + : base_type(first, last) + { + } + }; + + template< + class WrappedRange + , class Value = use_default + , class Traversal = use_default + , class Reference = use_default + , class Difference = use_default + , class Buffer = use_default + > + struct any_range_type_generator + { + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + typedef any_range< + typename any_range_value_type< + WrappedRange + , Value + , typename any_range_default_help< + Reference + , range_reference + >::type + >::type + , typename any_range_default_help< + Traversal + , iterator_traversal< + typename range_iterator::type + > + >::type + , typename any_range_default_help< + Reference + , range_reference + >::type + , typename any_range_default_help< + Difference + , range_difference + >::type + , typename any_range_default_help< + Buffer + , mpl::identity + >::type + > type; + }; + } // namespace range_detail + + using range_detail::any_range; + using range_detail::any_range_type_generator; +} // namespace boost + +#endif // include guard diff --git a/boost/range/as_array.hpp b/boost/range/as_array.hpp new file mode 100644 index 0000000..69a1580 --- /dev/null +++ b/boost/range/as_array.hpp @@ -0,0 +1,45 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_AS_ARRAY_HPP +#define BOOST_RANGE_AS_ARRAY_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost +{ + + template< class R > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + as_array( R& r ) + { + return boost::make_iterator_range( r ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class Range > + inline boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + as_array( const Range& r ) + { + return boost::make_iterator_range( r ); + } + +#endif + +} + +#endif + diff --git a/boost/range/as_literal.hpp b/boost/range/as_literal.hpp new file mode 100644 index 0000000..1c16e4a --- /dev/null +++ b/boost/range/as_literal.hpp @@ -0,0 +1,127 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_AS_LITERAL_HPP +#define BOOST_RANGE_AS_LITERAL_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +#include +#else + +#include +#include + +#include + +#include +#ifndef BOOST_NO_CWCHAR +#include +#endif + +namespace boost +{ + namespace range_detail + { + inline std::size_t length( const char* s ) + { + return strlen( s ); + } + +#ifndef BOOST_NO_CWCHAR + inline std::size_t length( const wchar_t* s ) + { + return wcslen( s ); + } +#endif + + // + // Remark: the compiler cannot choose between T* and T[sz] + // overloads, so we must put the T* internal to the + // unconstrained version. + // + + inline bool is_char_ptr( char* ) + { + return true; + } + + inline bool is_char_ptr( const char* ) + { + return true; + } + +#ifndef BOOST_NO_CWCHAR + inline bool is_char_ptr( wchar_t* ) + { + return true; + } + + inline bool is_char_ptr( const wchar_t* ) + { + return true; + } +#endif + + template< class T > + inline long is_char_ptr( const T& /* r */ ) + { + return 0L; + } + + template< class T > + inline iterator_range + make_range( T* const r, bool ) + { + return iterator_range( r, r + length(r) ); + } + + template< class T > + inline iterator_range::type> + make_range( T& r, long ) + { + return boost::make_iterator_range( r ); + } + + } + + template< class Range > + inline iterator_range::type> + as_literal( Range& r ) + { + return range_detail::make_range( r, range_detail::is_char_ptr(r) ); + } + + template< class Range > + inline iterator_range::type> + as_literal( const Range& r ) + { + return range_detail::make_range( r, range_detail::is_char_ptr(r) ); + } + + template< class Char, std::size_t sz > + inline iterator_range as_literal( Char (&arr)[sz] ) + { + return range_detail::make_range( arr, range_detail::is_char_ptr(arr) ); + } + + template< class Char, std::size_t sz > + inline iterator_range as_literal( const Char (&arr)[sz] ) + { + return range_detail::make_range( arr, range_detail::is_char_ptr(arr) ); + } +} + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +#endif diff --git a/boost/range/atl.hpp b/boost/range/atl.hpp new file mode 100644 index 0000000..e6500e5 --- /dev/null +++ b/boost/range/atl.hpp @@ -0,0 +1,724 @@ +#ifndef BOOST_RANGE_ATL_HPP +#define BOOST_RANGE_ATL_HPP + + + + +// Boost.Range ATL Extension +// +// Copyright Shunsuke Sogame 2005-2006. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + + +// config +// + + +#include // _ATL_VER + + +#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + #if (_ATL_VER < 0x0700) + #define BOOST_RANGE_ATL_NO_COLLECTIONS + #endif +#endif + + +#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + #if (_ATL_VER < 0x0700) // dubious + #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX + #endif +#endif + + +// forward declarations +// + + +#include // IID + + +namespace ATL { + + +#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + + + // arrays + // + template< class E, class ETraits > + class CAtlArray; + + template< class E > + class CAutoPtrArray; + + template< class I, const IID *piid > + class CInterfaceArray; + + + // lists + // + template< class E, class ETraits > + class CAtlList; + + template< class E > + class CAutoPtrList; + + template< class E, class Allocator > + class CHeapPtrList; + + template< class I, const IID *piid > + class CInterfaceList; + + + // maps + // + template< class K, class V, class KTraits, class VTraits > + class CAtlMap; + + template< class K, class V, class KTraits, class VTraits > + class CRBTree; + + template< class K, class V, class KTraits, class VTraits > + class CRBMap; + + template< class K, class V, class KTraits, class VTraits > + class CRBMultiMap; + + + // strings + // +#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) + template< class BaseType, bool t_bMFCDLL > + class CSimpleStringT; +#else + template< class BaseType > + class CSimpleStringT; +#endif + + template< class BaseType, class StringTraits > + class CStringT; + + template< class StringType, int t_nChars > + class CFixedStringT; + + template< class BaseType, const int t_nSize > + class CStaticString; + + +#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + + + // simples + // +#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + + template< class T, class TEqual > + class CSimpleArray; + + template< class TKey, class TVal, class TEqual > + class CSimpleMap; + +#else + + template< class T > + class CSimpleArray; + + template< class T > + class CSimpleValArray; + + template< class TKey, class TVal > + class CSimpleMap; + +#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + + + // pointers + // + template< class E > + class CAutoPtr; + + template< class T > + class CComPtr; + + template< class T, const IID *piid > + class CComQIPtr; + + template< class E, class Allocator > + class CHeapPtr; + + template< class T > + class CAdapt; + + +} // namespace ATL + + + + +// indirect_iterator customizations +// + + +#include +#include + + +namespace boost { + + + template< class E > + struct pointee< ATL::CAutoPtr > : + mpl::identity + { }; + + template< class T > + struct pointee< ATL::CComPtr > : + mpl::identity + { }; + + template< class T, const IID *piid > + struct pointee< ATL::CComQIPtr > : + mpl::identity + { }; + + template< class E, class Allocator > + struct pointee< ATL::CHeapPtr > : + mpl::identity + { }; + + template< class T > + struct pointee< ATL::CAdapt > : + pointee + { }; + + +} // namespace boost + + + + +// extended customizations +// + + +#include +#include +#include +#include +#include // CComBSTR + + +namespace boost { namespace range_detail_microsoft { + + +#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + + + // arrays + // + + struct atl_array_functions : + array_functions + { + template< class Iterator, class X > + Iterator end(X& x) // redefine + { + return x.GetData() + x.GetCount(); // no 'GetSize()' + } + }; + + + template< class E, class ETraits > + struct customization< ATL::CAtlArray > : + atl_array_functions + { + template< class X > + struct meta + { + typedef E val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< class E > + struct customization< ATL::CAutoPtrArray > : + atl_array_functions + { + template< class X > + struct meta + { + // ATL::CAutoPtr/CHeapPtr is no assignable. + typedef ATL::CAutoPtr val_t; + typedef val_t *miter_t; + typedef val_t const *citer_t; + + typedef indirect_iterator mutable_iterator; + typedef indirect_iterator const_iterator; + }; + }; + + + template< class I, const IID *piid > + struct customization< ATL::CInterfaceArray > : + atl_array_functions + { + template< class X > + struct meta + { + typedef ATL::CComQIPtr val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< class E, class ETraits > + struct customization< ATL::CAtlList > : + list_functions + { + template< class X > + struct meta + { + typedef E val_t; + + typedef list_iterator mutable_iterator; + typedef list_iterator const_iterator; + }; + }; + + + struct indirected_list_functions + { + template< class Iterator, class X > + Iterator begin(X& x) + { + typedef typename Iterator::base_type base_t; // == list_iterator + return Iterator(base_t(x, x.GetHeadPosition())); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + typedef typename Iterator::base_type base_t; + return Iterator(base_t(x, POSITION(0))); + } + }; + + + template< class E > + struct customization< ATL::CAutoPtrList > : + indirected_list_functions + { + template< class X > + struct meta + { + typedef ATL::CAutoPtr val_t; + typedef list_iterator miter_t; + typedef list_iterator citer_t; + + typedef indirect_iterator mutable_iterator; + typedef indirect_iterator const_iterator; + }; + }; + + + template< class E, class Allocator > + struct customization< ATL::CHeapPtrList > : + indirected_list_functions + { + template< class X > + struct meta + { + typedef ATL::CHeapPtr val_t; + typedef list_iterator miter_t; + typedef list_iterator citer_t; + + typedef indirect_iterator mutable_iterator; + typedef indirect_iterator const_iterator; + }; + }; + + + template< class I, const IID *piid > + struct customization< ATL::CInterfaceList > : + list_functions + { + template< class X > + struct meta + { + typedef ATL::CComQIPtr val_t; + + typedef list_iterator mutable_iterator; + typedef list_iterator const_iterator; + }; + }; + + + // maps + // + + struct atl_rb_tree_tag + { }; + + template< > + struct customization< atl_rb_tree_tag > : + indirected_list_functions + { + template< class X > + struct meta + { + typedef typename X::CPair val_t; + + typedef list_iterator miter_t; + typedef list_iterator citer_t; + + typedef indirect_iterator mutable_iterator; + typedef indirect_iterator const_iterator; + }; + }; + + + template< class K, class V, class KTraits, class VTraits > + struct customization< ATL::CAtlMap > : + customization< atl_rb_tree_tag > + { + template< class Iterator, class X > + Iterator begin(X& x) // redefine + { + typedef typename Iterator::base_type base_t; // == list_iterator + return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition' + } + }; + + + // strings + // + + struct atl_string_tag + { }; + + template< > + struct customization< atl_string_tag > + { + template< class X > + struct meta + { + typedef typename X::PXSTR mutable_iterator; + typedef typename X::PCXSTR const_iterator; + }; + + template< class Iterator, class X > + typename mutable_::type begin(X& x) + { + return x.GetBuffer(0); + } + + template< class Iterator, class X > + Iterator begin(X const& x) + { + return x.GetString(); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return begin(x) + x.GetLength(); + } + }; + + + template< class BaseType, const int t_nSize > + struct customization< ATL::CStaticString > + { + template< class X > + struct meta + { + typedef BaseType const *mutable_iterator; + typedef mutable_iterator const_iterator; + }; + + template< class Iterator, class X > + Iterator begin(X const& x) + { + return x; + } + + template< class Iterator, class X > + Iterator end(X const& x) + { + return begin(x) + X::GetLength(); + } + }; + + +#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + + + template< > + struct customization< ATL::CComBSTR > + { + template< class X > + struct meta + { + typedef OLECHAR *mutable_iterator; + typedef OLECHAR const *const_iterator; + }; + + template< class Iterator, class X > + Iterator begin(X& x) + { + return x.operator BSTR(); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return begin(x) + x.Length(); + } + }; + + + // simples + // + +#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + template< class T, class TEqual > + struct customization< ATL::CSimpleArray > : +#else + template< class T > + struct customization< ATL::CSimpleArray > : +#endif + array_functions + { + template< class X > + struct meta + { + typedef T val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + +#if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + + template< class T > + struct customization< ATL::CSimpleValArray > : + array_functions + { + template< class X > + struct meta + { + typedef T val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + +#endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + + +#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + template< class TKey, class TVal, class TEqual > + struct customization< ATL::CSimpleMap > +#else + template< class TKey, class TVal > + struct customization< ATL::CSimpleMap > +#endif + { + template< class X > + struct meta + { + typedef TKey k_val_t; + typedef k_val_t *k_miter_t; + typedef k_val_t const *k_citer_t; + + typedef TVal v_val_t; + typedef v_val_t *v_miter_t; + typedef v_val_t const *v_citer_t; + + // Topic: + // 'std::pair' can't contain references + // because of reference to reference problem. + + typedef zip_iterator< tuple > mutable_iterator; + typedef zip_iterator< tuple > const_iterator; + }; + + template< class Iterator, class X > + Iterator begin(X& x) + { + return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal)); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize())); + } + }; + + +} } // namespace boost::range_detail_microsoft + + + + +// range customizations +// + + +#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + + + // arrays + // + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CAtlArray, 2 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CAutoPtrArray, 1 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *) + ) + + + // lists + // + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CAtlList, 2 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CAutoPtrList, 1 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CHeapPtrList, 2 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *) + ) + + + //maps + // + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CAtlMap, 4 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_rb_tree_tag, + (ATL, BOOST_PP_NIL), CRBTree, 4 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_rb_tree_tag, + (ATL, BOOST_PP_NIL), CRBMap, 4 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_rb_tree_tag, + (ATL, BOOST_PP_NIL), CRBMultiMap, 4 + ) + + + // strings + // + #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_string_tag, + (ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool) + ) + #else + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_string_tag, + (ATL, BOOST_PP_NIL), CSimpleStringT, 1 + ) + #endif + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_string_tag, + (ATL, BOOST_PP_NIL), CStringT, 2 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::atl_string_tag, + (ATL, BOOST_PP_NIL), CFixedStringT, (class)(int) + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CStaticString, (class)(const int) + ) + + +#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) + + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CComBSTR +) + + +// simples +// +#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CSimpleArray, 2 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CSimpleMap, 3 + ) + +#else + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CSimpleArray, 1 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CSimpleMap, 2 + ) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + (ATL, BOOST_PP_NIL), CSimpleValArray, 1 + ) + +#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) + + + + +#endif diff --git a/boost/range/begin.hpp b/boost/range/begin.hpp new file mode 100644 index 0000000..ba5a73b --- /dev/null +++ b/boost/range/begin.hpp @@ -0,0 +1,135 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_BEGIN_HPP +#define BOOST_RANGE_BEGIN_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +#include +#else + +#include + +namespace boost +{ + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +namespace range_detail +{ +#endif + + ////////////////////////////////////////////////////////////////////// + // primary template + ////////////////////////////////////////////////////////////////////// + + template< typename C > + inline BOOST_DEDUCED_TYPENAME range_iterator::type + range_begin( C& c ) + { + // + // If you get a compile-error here, it is most likely because + // you have not implemented range_begin() properly in + // the namespace of C + // + return c.begin(); + } + + ////////////////////////////////////////////////////////////////////// + // pair + ////////////////////////////////////////////////////////////////////// + + template< typename Iterator > + inline Iterator range_begin( const std::pair& p ) + { + return p.first; + } + + template< typename Iterator > + inline Iterator range_begin( std::pair& p ) + { + return p.first; + } + + ////////////////////////////////////////////////////////////////////// + // array + ////////////////////////////////////////////////////////////////////// + + // + // May this be discarded? Or is it needed for bad compilers? + // + template< typename T, std::size_t sz > + inline const T* range_begin( const T (&a)[sz] ) + { + return a; + } + + template< typename T, std::size_t sz > + inline T* range_begin( T (&a)[sz] ) + { + return a; + } + + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +} // namespace 'range_detail' +#endif + +// Use a ADL namespace barrier to avoid ambiguity with other unqualified +// calls. This is particularly important with C++0x encouraging +// unqualified calls to begin/end. +namespace range_adl_barrier +{ + +template< class T > +inline BOOST_DEDUCED_TYPENAME range_iterator::type begin( T& r ) +{ +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + using namespace range_detail; +#endif + return range_begin( r ); +} + +template< class T > +inline BOOST_DEDUCED_TYPENAME range_iterator::type begin( const T& r ) +{ +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + using namespace range_detail; +#endif + return range_begin( r ); +} + + } // namespace range_adl_barrier +} // namespace boost + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +namespace boost +{ + namespace range_adl_barrier + { + template< class T > + inline BOOST_DEDUCED_TYPENAME range_iterator::type + const_begin( const T& r ) + { + return boost::range_adl_barrier::begin( r ); + } + } // namespace range_adl_barrier + + using namespace range_adl_barrier; +} // namespace boost + +#endif + diff --git a/boost/range/category.hpp b/boost/range/category.hpp new file mode 100644 index 0000000..f5431ad --- /dev/null +++ b/boost/range/category.hpp @@ -0,0 +1,29 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_CATEGORY_HPP +#define BOOST_RANGE_CATEGORY_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + template< class T > + struct range_category : iterator_category< typename range_iterator::type > + { }; +} + +#endif diff --git a/boost/range/combine.hpp b/boost/range/combine.hpp new file mode 100644 index 0000000..26cef9a --- /dev/null +++ b/boost/range/combine.hpp @@ -0,0 +1,45 @@ +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_COMBINE_HPP +#define BOOST_RANGE_COMBINE_HPP + +#include +#include +#include + +namespace boost +{ + namespace range + { + +template +class combined_range + : public iterator_range > +{ + typedef iterator_range > base; +public: + combined_range(IterTuple first, IterTuple last) + : base(first, last) + { + } +}; + + } // namespace range +} // namespace boost + +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \ + defined(BOOST_NO_CXX11_DECLTYPE) || \ + defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \ + defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +# include +#else +# include +#endif + +#endif diff --git a/boost/range/concepts.hpp b/boost/range/concepts.hpp new file mode 100644 index 0000000..3e612a3 --- /dev/null +++ b/boost/range/concepts.hpp @@ -0,0 +1,386 @@ +// Boost.Range library concept checks +// +// Copyright Neil Groves 2009. Use, modification and distribution +// are subject to the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Copyright Daniel Walker 2006. Use, modification and distribution +// are subject to the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_CONCEPTS_HPP +#define BOOST_RANGE_CONCEPTS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + * \file + * \brief Concept checks for the Boost Range library. + * + * The structures in this file may be used in conjunction with the + * Boost Concept Check library to insure that the type of a function + * parameter is compatible with a range concept. If not, a meaningful + * compile time error is generated. Checks are provided for the range + * concepts related to iterator traversal categories. For example, the + * following line checks that the type T models the ForwardRange + * concept. + * + * \code + * BOOST_CONCEPT_ASSERT((ForwardRangeConcept)); + * \endcode + * + * A different concept check is required to ensure writeable value + * access. For example to check for a ForwardRange that can be written + * to, the following code is required. + * + * \code + * BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept)); + * \endcode + * + * \see http://www.boost.org/libs/range/doc/range.html for details + * about range concepts. + * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html + * for details about iterator concepts. + * \see http://www.boost.org/libs/concept_check/concept_check.htm for + * details about concept checks. + */ + +namespace boost { + + namespace range_detail { + +#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT + +// List broken compiler versions here: +#ifndef __clang__ + #ifdef __GNUC__ + // GNUC 4.2 has strange issues correctly detecting compliance with the Concepts + // hence the least disruptive approach is to turn-off the concept checking for + // this version of the compiler. + #if __GNUC__ == 4 && __GNUC_MINOR__ == 2 + #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0 + #endif + #endif + + #ifdef __GCCXML__ + // GCC XML, unsurprisingly, has the same issues + #if __GCCXML_GNUC__ == 4 && __GCCXML_GNUC_MINOR__ == 2 + #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0 + #endif + #endif +#endif + + #ifdef __BORLANDC__ + #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0 + #endif + + #ifdef __PATHCC__ + #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0 + #endif + +// Default to using the concept asserts unless we have defined it off +// during the search for black listed compilers. + #ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT + #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1 + #endif + +#endif + +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + #define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x ) +#else + #define BOOST_RANGE_CONCEPT_ASSERT( x ) +#endif + + // Rationale for the inclusion of redefined iterator concept + // classes: + // + // The Range algorithms often do not require that the iterators are + // Assignable or default constructable, but the correct standard + // conformant iterators do require the iterators to be a model of the + // Assignable concept. + // Iterators that contains a functor that is not assignable therefore + // are not correct models of the standard iterator concepts, + // despite being adequate for most algorithms. An example of this + // use case is the combination of the boost::adaptors::filtered + // class with a boost::lambda::bind generated functor. + // Ultimately modeling the range concepts using composition + // with the Boost.Iterator concepts would render the library + // incompatible with many common Boost.Lambda expressions. + template + struct IncrementableIteratorConcept : CopyConstructible + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + typedef BOOST_DEDUCED_TYPENAME iterator_traversal::type traversal_category; + + BOOST_RANGE_CONCEPT_ASSERT(( + Convertible< + traversal_category, + incrementable_traversal_tag + >)); + + BOOST_CONCEPT_USAGE(IncrementableIteratorConcept) + { + ++i; + (void)i++; + } + private: + Iterator i; +#endif + }; + + template + struct SinglePassIteratorConcept + : IncrementableIteratorConcept + , EqualityComparable + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + BOOST_RANGE_CONCEPT_ASSERT(( + Convertible< + BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category, + single_pass_traversal_tag + >)); + + BOOST_CONCEPT_USAGE(SinglePassIteratorConcept) + { + Iterator i2(++i); + boost::ignore_unused_variable_warning(i2); + + // deliberately we are loose with the postfix version for the single pass + // iterator due to the commonly poor adherence to the specification means that + // many algorithms would be unusable, whereas actually without the check they + // work + (void)(i++); + + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r1(*i); + boost::ignore_unused_variable_warning(r1); + + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r2(*(++i)); + boost::ignore_unused_variable_warning(r2); + } + private: + Iterator i; +#endif + }; + + template + struct ForwardIteratorConcept + : SinglePassIteratorConcept + , DefaultConstructible + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::difference_type difference_type; + + BOOST_MPL_ASSERT((is_integral)); + BOOST_MPL_ASSERT_RELATION(std::numeric_limits::is_signed, ==, true); + + BOOST_RANGE_CONCEPT_ASSERT(( + Convertible< + BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category, + forward_traversal_tag + >)); + + BOOST_CONCEPT_USAGE(ForwardIteratorConcept) + { + // See the above note in the SinglePassIteratorConcept about the handling of the + // postfix increment. Since with forward and better iterators there is no need + // for a proxy, we can sensibly require that the dereference result + // is convertible to reference. + Iterator i2(i++); + boost::ignore_unused_variable_warning(i2); + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r(*(i++)); + boost::ignore_unused_variable_warning(r); + } + private: + Iterator i; +#endif + }; + + template + struct BidirectionalIteratorConcept + : ForwardIteratorConcept + { + #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + BOOST_RANGE_CONCEPT_ASSERT(( + Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category, + bidirectional_traversal_tag + >)); + + BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept) + { + --i; + (void)i--; + } + private: + Iterator i; + #endif + }; + + template + struct RandomAccessIteratorConcept + : BidirectionalIteratorConcept + { + #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + BOOST_RANGE_CONCEPT_ASSERT(( + Convertible< + BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category, + random_access_traversal_tag + >)); + + BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept) + { + i += n; + i = i + n; + i = n + i; + i -= n; + i = i - n; + n = i - j; + } + private: + BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n; + Iterator i; + Iterator j; + #endif + }; + + } // namespace range_detail + + //! Check if a type T models the SinglePassRange range concept. + template + struct SinglePassRangeConcept + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + // A few compilers don't like the rvalue reference T types so just + // remove it. + typedef BOOST_DEDUCED_TYPENAME remove_reference::type Rng; + + typedef BOOST_DEDUCED_TYPENAME range_iterator< + Rng const + >::type const_iterator; + + typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator; + + BOOST_RANGE_CONCEPT_ASSERT(( + range_detail::SinglePassIteratorConcept)); + + BOOST_RANGE_CONCEPT_ASSERT(( + range_detail::SinglePassIteratorConcept)); + + BOOST_CONCEPT_USAGE(SinglePassRangeConcept) + { + // This has been modified from assigning to this->i + // (where i was a member variable) to improve + // compatibility with Boost.Lambda + iterator i1 = boost::begin(*m_range); + iterator i2 = boost::end(*m_range); + + boost::ignore_unused_variable_warning(i1); + boost::ignore_unused_variable_warning(i2); + + const_constraints(*m_range); + } + + private: + void const_constraints(const Rng& const_range) + { + const_iterator ci1 = boost::begin(const_range); + const_iterator ci2 = boost::end(const_range); + + boost::ignore_unused_variable_warning(ci1); + boost::ignore_unused_variable_warning(ci2); + } + + // Rationale: + // The type of m_range is T* rather than T because it allows + // T to be an abstract class. The other obvious alternative of + // T& produces a warning on some compilers. + Rng* m_range; +#endif + }; + + //! Check if a type T models the ForwardRange range concept. + template + struct ForwardRangeConcept : SinglePassRangeConcept + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept)); + BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept)); +#endif + }; + + template + struct WriteableRangeConcept + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator; + + BOOST_CONCEPT_USAGE(WriteableRangeConcept) + { + *i = v; + } + private: + iterator i; + BOOST_DEDUCED_TYPENAME range_value::type v; +#endif + }; + + //! Check if a type T models the WriteableForwardRange range concept. + template + struct WriteableForwardRangeConcept + : ForwardRangeConcept + , WriteableRangeConcept + { + }; + + //! Check if a type T models the BidirectionalRange range concept. + template + struct BidirectionalRangeConcept : ForwardRangeConcept + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept)); + BOOST_RANGE_CONCEPT_ASSERT((range_detail::BidirectionalIteratorConcept)); +#endif + }; + + //! Check if a type T models the WriteableBidirectionalRange range concept. + template + struct WriteableBidirectionalRangeConcept + : BidirectionalRangeConcept + , WriteableRangeConcept + { + }; + + //! Check if a type T models the RandomAccessRange range concept. + template + struct RandomAccessRangeConcept : BidirectionalRangeConcept + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT + BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept)); + BOOST_RANGE_CONCEPT_ASSERT((range_detail::RandomAccessIteratorConcept)); +#endif + }; + + //! Check if a type T models the WriteableRandomAccessRange range concept. + template + struct WriteableRandomAccessRangeConcept + : RandomAccessRangeConcept + , WriteableRangeConcept + { + }; + +} // namespace boost + +#endif // BOOST_RANGE_CONCEPTS_HPP diff --git a/boost/range/config.hpp b/boost/range/config.hpp new file mode 100644 index 0000000..7600a5f --- /dev/null +++ b/boost/range/config.hpp @@ -0,0 +1,56 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_CONFIG_HPP +#define BOOST_RANGE_CONFIG_HPP + +#include + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#ifdef BOOST_RANGE_DEDUCED_TYPENAME +#error "macro already defined!" +#endif + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# define BOOST_RANGE_DEDUCED_TYPENAME typename +#else +#define BOOST_RANGE_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME +#endif + +#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT +#error "macro already defined!" +#endif + +#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 ) +#define BOOST_RANGE_NO_ARRAY_SUPPORT 1 +#endif + +#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT +#define BOOST_RANGE_ARRAY_REF() (boost_range_array) +#define BOOST_RANGE_NO_STATIC_ASSERT +#else +#define BOOST_RANGE_ARRAY_REF() (&boost_range_array) +#endif + +#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) +# define BOOST_RANGE_UNUSED __attribute__((unused)) +#else +# define BOOST_RANGE_UNUSED +#endif + + + +#endif + diff --git a/boost/range/const_iterator.hpp b/boost/range/const_iterator.hpp new file mode 100644 index 0000000..3413e59 --- /dev/null +++ b/boost/range/const_iterator.hpp @@ -0,0 +1,76 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_CONST_ITERATOR_HPP +#define BOOST_RANGE_CONST_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + ////////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////////// + + namespace range_detail + { + +BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator ) + +template< typename C > +struct range_const_iterator + : extract_const_iterator +{}; + +////////////////////////////////////////////////////////////////////////// +// pair +////////////////////////////////////////////////////////////////////////// + +template< typename Iterator > +struct range_const_iterator > +{ + typedef Iterator type; +}; + +////////////////////////////////////////////////////////////////////////// +// array +////////////////////////////////////////////////////////////////////////// + +template< typename T, std::size_t sz > +struct range_const_iterator< T[sz] > +{ + typedef const T* type; +}; + + } // namespace range_detail + +template +struct range_const_iterator + : range_detail::range_const_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type + > +{ +}; + +} // namespace boost + + +#endif diff --git a/boost/range/const_reverse_iterator.hpp b/boost/range/const_reverse_iterator.hpp new file mode 100644 index 0000000..bfe1615 --- /dev/null +++ b/boost/range/const_reverse_iterator.hpp @@ -0,0 +1,35 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP +#define BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost +{ + // + // This interface is deprecated, use range_reverse_iterator + // + + template< typename C > + struct range_const_reverse_iterator + : range_reverse_iterator< + const BOOST_DEDUCED_TYPENAME remove_reference::type> + { }; + +} // namespace boost + +#endif diff --git a/boost/range/counting_range.hpp b/boost/range/counting_range.hpp new file mode 100644 index 0000000..d886a21 --- /dev/null +++ b/boost/range/counting_range.hpp @@ -0,0 +1,76 @@ +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED +#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED + +#include +#if BOOST_MSVC >= 1400 +#pragma warning(push) +#pragma warning(disable : 4244) +#endif + +#include +#include +#include +#include + +namespace boost +{ + template + inline iterator_range > + counting_range(Value first, Value last) + { + typedef counting_iterator counting_iterator_t; + typedef iterator_range result_t; + return result_t(counting_iterator_t(first), + counting_iterator_t(last)); + } + + template + inline iterator_range< + counting_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + counting_range(const Range& rng) + { + typedef counting_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > counting_iterator_t; + + typedef iterator_range result_t; + + return result_t(counting_iterator_t(boost::begin(rng)), + counting_iterator_t(boost::end(rng))); + } + + template + inline iterator_range< + counting_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > + > + counting_range(Range& rng) + { + typedef counting_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type + > counting_iterator_t; + + typedef iterator_range result_t; + + return result_t(counting_iterator_t(boost::begin(rng)), + counting_iterator_t(boost::end(rng))); + } +} // namespace boost + +#if BOOST_MSVC >= 1400 +#pragma warning(pop) +#endif + +#endif // include guard diff --git a/boost/range/detail/any_iterator.hpp b/boost/range/detail/any_iterator.hpp new file mode 100644 index 0000000..555bd57 --- /dev/null +++ b/boost/range/detail/any_iterator.hpp @@ -0,0 +1,587 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // metafunction to determine if T is a const reference + template + struct is_const_reference + { + typedef typename mpl::and_< + typename is_reference::type, + typename is_const< + typename remove_reference::type + >::type + >::type type; + }; + + // metafunction to determine if T is a mutable reference + template + struct is_mutable_reference + { + typedef typename mpl::and_< + typename is_reference::type, + typename mpl::not_< + typename is_const< + typename remove_reference::type + >::type + >::type + >::type type; + }; + + // metafunction to evaluate if a source 'reference' can be + // converted to a target 'reference' as a value. + // + // This is true, when the target reference type is actually + // not a reference, and the source reference is convertible + // to the target type. + template + struct is_convertible_to_value_as_reference + { + typedef typename mpl::and_< + typename mpl::not_< + typename is_reference::type + >::type + , typename is_convertible< + SourceReference + , TargetReference + >::type + >::type type; + }; + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer = any_iterator_default_buffer + > + class any_iterator; + + // metafunction to determine if SomeIterator is an + // any_iterator. + // + // This is the general implementation which evaluates to false. + template + struct is_any_iterator + : mpl::bool_ + { + }; + + // specialization of is_any_iterator to return true for + // any_iterator classes regardless of template parameters. + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + struct is_any_iterator< + any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > + : mpl::bool_ + { + }; + } // namespace range_detail + + namespace detail + { + // Rationale: + // These are specialized since the iterator_facade versions lack + // the requisite typedefs to allow wrapping to determine the types + // if a user copy constructs from a postfix increment. + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + class postfix_increment_proxy< + range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > + { + typedef range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > any_iterator_type; + + public: + typedef Value value_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef Difference difference_type; + typedef typename iterator_pointer::type pointer; + typedef Reference reference; + + explicit postfix_increment_proxy(any_iterator_type const& x) + : stored_value(*x) + {} + + value_type& + operator*() const + { + return this->stored_value; + } + private: + mutable value_type stored_value; + }; + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + class writable_postfix_increment_proxy< + range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > + { + typedef range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > any_iterator_type; + public: + typedef Value value_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef Difference difference_type; + typedef typename iterator_pointer::type pointer; + typedef Reference reference; + + explicit writable_postfix_increment_proxy(any_iterator_type const& x) + : stored_value(*x) + , stored_iterator(x) + {} + + // Dereferencing must return a proxy so that both *r++ = o and + // value_type(*r++) can work. In this case, *r is the same as + // *r++, and the conversion operator below is used to ensure + // readability. + writable_postfix_increment_proxy const& + operator*() const + { + return *this; + } + + // Provides readability of *r++ + operator value_type&() const + { + return stored_value; + } + + // Provides writability of *r++ + template + T const& operator=(T const& x) const + { + *this->stored_iterator = x; + return x; + } + + // This overload just in case only non-const objects are writable + template + T& operator=(T& x) const + { + *this->stored_iterator = x; + return x; + } + + // Provides X(r++) + operator any_iterator_type const&() const + { + return stored_iterator; + } + + private: + mutable value_type stored_value; + any_iterator_type stored_iterator; + }; + + + } + + namespace range_detail + { + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + class any_iterator + : public iterator_facade< + any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + , Value + , Traversal + , Reference + , Difference + > + { + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + , class OtherBuffer + > + friend class any_iterator; + + struct enabler {}; + struct disabler {}; + + typedef typename any_iterator_interface_type_generator< + Traversal + , Reference + , Difference + , Buffer + >::type abstract_base_type; + + typedef iterator_facade< + any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + , Value + , Traversal + , Reference + , Difference + > base_type; + + typedef Buffer buffer_type; + + public: + typedef typename base_type::value_type value_type; + typedef typename base_type::reference reference; + typedef typename base_type::difference_type difference_type; + + // Default constructor + any_iterator() + : m_impl(0) {} + + // Simple copy construction without conversion + any_iterator(const any_iterator& other) + : base_type(other) + , m_impl(other.m_impl + ? other.m_impl->clone(m_buffer) + : 0) + { + } + + // Simple assignment operator without conversion + any_iterator& operator=(const any_iterator& other) + { + if (this != &other) + { + if (m_impl) + m_impl->~abstract_base_type(); + m_buffer.deallocate(); + m_impl = 0; + if (other.m_impl) + m_impl = other.m_impl->clone(m_buffer); + } + return *this; + } + + // Implicit conversion from another any_iterator where the + // conversion is from a non-const reference to a const reference + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_iterator(const any_iterator< + OtherValue, + OtherTraversal, + OtherReference, + OtherDifference, + Buffer + >& other, + typename ::boost::enable_if< + typename mpl::and_< + typename is_mutable_reference::type, + typename is_const_reference::type + >::type, + enabler + >::type* = 0 + ) + : m_impl(other.m_impl + ? other.m_impl->clone_const_ref(m_buffer) + : 0 + ) + { + } + + // Implicit conversion from another any_iterator where the + // reference types of the source and the target are references + // that are either both const, or both non-const. + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_iterator(const any_iterator< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other, + typename ::boost::enable_if< + typename mpl::or_< + typename mpl::and_< + typename is_mutable_reference::type, + typename is_mutable_reference::type + >::type, + typename mpl::and_< + typename is_const_reference::type, + typename is_const_reference::type + >::type + >::type, + enabler + >::type* = 0 + ) + : m_impl(other.m_impl + ? other.m_impl->clone(m_buffer) + : 0 + ) + { + } + + // Implicit conversion to an any_iterator that uses a value for + // the reference type. + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_iterator(const any_iterator< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other, + typename ::boost::enable_if< + typename is_convertible_to_value_as_reference< + OtherReference + , Reference + >::type, + enabler + >::type* = 0 + ) + : m_impl(other.m_impl + ? other.m_impl->clone_reference_as_value(m_buffer) + : 0 + ) + { + } + + any_iterator clone() const + { + any_iterator result; + if (m_impl) + result.m_impl = m_impl->clone(result.m_buffer); + return result; + } + + any_iterator< + Value + , Traversal + , typename abstract_base_type::const_reference + , Difference + , Buffer + > + clone_const_ref() const + { + typedef any_iterator< + Value + , Traversal + , typename abstract_base_type::const_reference + , Difference + , Buffer + > result_type; + + result_type result; + + if (m_impl) + result.m_impl = m_impl->clone_const_ref(result.m_buffer); + + return result; + } + + // implicit conversion and construction from type-erasure-compatible + // iterators + template + explicit any_iterator( + const WrappedIterator& wrapped_iterator, + typename disable_if< + typename is_any_iterator::type + , disabler + >::type* = 0 + ) + { + typedef typename any_iterator_wrapper_type_generator< + WrappedIterator + , Traversal + , Reference + , Difference + , Buffer + >::type wrapper_type; + + void* ptr = m_buffer.allocate(sizeof(wrapper_type)); + m_impl = new(ptr) wrapper_type(wrapped_iterator); + } + + ~any_iterator() + { + // manually run the destructor, the deallocation is automatically + // handled by the any_iterator_small_buffer base class. + if (m_impl) + m_impl->~abstract_base_type(); + } + + private: + friend class ::boost::iterator_core_access; + + Reference dereference() const + { + BOOST_ASSERT( m_impl ); + return m_impl->dereference(); + } + + bool equal(const any_iterator& other) const + { + return (m_impl == other.m_impl) + || (m_impl && other.m_impl && m_impl->equal(*other.m_impl)); + } + + void increment() + { + BOOST_ASSERT( m_impl ); + m_impl->increment(); + } + + void decrement() + { + BOOST_ASSERT( m_impl ); + m_impl->decrement(); + } + + Difference distance_to(const any_iterator& other) const + { + return m_impl && other.m_impl + ? m_impl->distance_to(*other.m_impl) + : 0; + } + + void advance(Difference offset) + { + BOOST_ASSERT( m_impl ); + m_impl->advance(offset); + } + + any_iterator& swap(any_iterator& other) + { + BOOST_ASSERT( this != &other ); + // grab a temporary copy of the other iterator + any_iterator tmp(other); + + // deallocate the other iterator, taking care to obey the + // class-invariants in-case of exceptions later + if (other.m_impl) + { + other.m_impl->~abstract_base_type(); + other.m_buffer.deallocate(); + other.m_impl = 0; + } + + // If this is a non-null iterator then we need to put + // a clone of this iterators implementation into the other + // iterator. + // We can't just swap because of the small buffer optimization. + if (m_impl) + { + other.m_impl = m_impl->clone(other.m_buffer); + m_impl->~abstract_base_type(); + m_buffer.deallocate(); + m_impl = 0; + } + + // assign to this instance a clone of the temporarily held + // tmp which represents the input other parameter at the + // start of execution of this function. + if (tmp.m_impl) + m_impl = tmp.m_impl->clone(m_buffer); + + return *this; + } + + buffer_type m_buffer; + abstract_base_type* m_impl; + }; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/any_iterator_buffer.hpp b/boost/range/detail/any_iterator_buffer.hpp new file mode 100644 index 0000000..2bb5d53 --- /dev/null +++ b/boost/range/detail/any_iterator_buffer.hpp @@ -0,0 +1,117 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost +{ + template + class any_iterator_buffer + : noncopyable + { + BOOST_STATIC_ASSERT(( StackBufferSize > 0 )); + public: + any_iterator_buffer() + : m_ptr() + { + } + + ~any_iterator_buffer() + { + delete [] m_ptr; + } + + void* allocate(std::size_t bytes) + { + BOOST_ASSERT( !m_ptr ); + if (bytes <= StackBufferSize) + return m_buffer.data(); + + m_ptr = new char[bytes]; + return m_ptr; + } + + void deallocate() + { + delete [] m_ptr; + m_ptr = 0; + } + + private: + // Rationale: + // Do not use inheritance from noncopyable because this causes + // the concepts to erroneous detect the derived any_iterator + // as noncopyable. + any_iterator_buffer(const any_iterator_buffer&); + void operator=(const any_iterator_buffer&); + + char* m_ptr; + boost::array m_buffer; + }; + + class any_iterator_heap_only_buffer + : noncopyable + { + public: + any_iterator_heap_only_buffer() + : m_ptr() + { + } + + ~any_iterator_heap_only_buffer() + { + delete [] m_ptr; + } + + void* allocate(std::size_t bytes) + { + BOOST_ASSERT( !m_ptr ); + m_ptr = new char[bytes]; + return m_ptr; + } + + void deallocate() + { + delete [] m_ptr; + m_ptr = 0; + } + + private: + char* m_ptr; + }; + + template + class any_iterator_stack_only_buffer + { + BOOST_STATIC_ASSERT(( StackBufferSize > 0 )); + public: + void* allocate(std::size_t bytes) + { + BOOST_ASSERT( bytes <= m_buffer.size() ); + return m_buffer.data(); + } + + void deallocate() + { + } + + private: + boost::array m_buffer; + }; + + typedef any_iterator_buffer<64> any_iterator_default_buffer; +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/any_iterator_interface.hpp b/boost/range/detail/any_iterator_interface.hpp new file mode 100644 index 0000000..cd56714 --- /dev/null +++ b/boost/range/detail/any_iterator_interface.hpp @@ -0,0 +1,277 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template + struct const_reference_type_generator + { + typedef typename mpl::if_< + typename is_reference::type, + typename add_const< + typename remove_reference::type + >::type&, + T + >::type type; + }; + + template + struct mutable_reference_type_generator + { + typedef typename mpl::if_< + typename mpl::and_< + typename is_const::type, + typename mpl::not_::type>::type + >::type, + T, + typename add_reference::type + >::type type; + }; + + template< + class Reference + , class Buffer + > + struct any_incrementable_iterator_interface + { + typedef typename mutable_reference_type_generator< + Reference + >::type reference; + + typedef typename const_reference_type_generator< + Reference + >::type const_reference; + + typedef typename remove_const< + typename remove_reference::type + >::type reference_as_value_type; + + typedef Buffer buffer_type; + + virtual ~any_incrementable_iterator_interface() {} + + virtual any_incrementable_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_incrementable_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_incrementable_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual void increment() = 0; + }; + + template< + class Reference + , class Buffer + > + struct any_single_pass_iterator_interface + : any_incrementable_iterator_interface + { + typedef typename any_incrementable_iterator_interface::reference reference; + typedef typename any_incrementable_iterator_interface::const_reference const_reference; + typedef typename any_incrementable_iterator_interface::buffer_type buffer_type; + typedef typename any_incrementable_iterator_interface::reference_as_value_type reference_as_value_type; + + virtual any_single_pass_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_single_pass_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_single_pass_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual reference dereference() const = 0; + + virtual bool equal(const any_single_pass_iterator_interface& other) const = 0; + }; + + template< + class Reference + , class Buffer + > + struct any_forward_iterator_interface + : any_single_pass_iterator_interface + { + typedef typename any_single_pass_iterator_interface::reference reference; + typedef typename any_single_pass_iterator_interface::const_reference const_reference; + typedef typename any_single_pass_iterator_interface::buffer_type buffer_type; + typedef typename any_single_pass_iterator_interface::reference_as_value_type reference_as_value_type; + + virtual any_forward_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_forward_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_forward_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + }; + + template< + class Reference + , class Buffer + > + struct any_bidirectional_iterator_interface + : any_forward_iterator_interface + { + typedef typename any_forward_iterator_interface::reference reference; + typedef typename any_forward_iterator_interface::const_reference const_reference; + typedef typename any_forward_iterator_interface::buffer_type buffer_type; + typedef typename any_forward_iterator_interface::reference_as_value_type reference_as_value_type; + + virtual any_bidirectional_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_bidirectional_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_bidirectional_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual void decrement() = 0; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_random_access_iterator_interface + : any_bidirectional_iterator_interface< + Reference + , Buffer + > + { + typedef typename any_bidirectional_iterator_interface::reference reference; + typedef typename any_bidirectional_iterator_interface::const_reference const_reference; + typedef typename any_bidirectional_iterator_interface::buffer_type buffer_type; + typedef typename any_bidirectional_iterator_interface::reference_as_value_type reference_as_value_type; + typedef Difference difference_type; + + virtual any_random_access_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_random_access_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_random_access_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual void advance(Difference offset) = 0; + + virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0; + }; + + template< + class Traversal + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + incrementable_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_incrementable_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + single_pass_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_single_pass_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + forward_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_forward_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + bidirectional_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_bidirectional_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + random_access_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_random_access_iterator_interface< + Reference + , Difference + , Buffer + > type; + }; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/any_iterator_wrapper.hpp b/boost/range/detail/any_iterator_wrapper.hpp new file mode 100644 index 0000000..bcd9b7f --- /dev/null +++ b/boost/range/detail/any_iterator_wrapper.hpp @@ -0,0 +1,640 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template + TargetT& polymorphic_ref_downcast(SourceT& source) + { +#ifdef BOOST_NO_RTTI + return static_cast(source); +#else + return *boost::polymorphic_downcast(&source); +#endif + } + + template + Reference dereference_cast(T& x) + { + return static_cast(x); + } + template + Reference dereference_cast(const T& x) + { + return static_cast(const_cast(x)); + } + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_incrementable_iterator_wrapper + : public any_incrementable_iterator_interface< + Reference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept )); + public: + typedef WrappedIterator wrapped_type; + + BOOST_STATIC_ASSERT(( is_convertible< + typename iterator_reference::type + , Reference + >::value )); + + any_incrementable_iterator_wrapper() + : m_it() + {} + + explicit any_incrementable_iterator_wrapper(wrapped_type it) + : m_it(it) + {} + + // any_incrementable_iterator implementation + virtual any_incrementable_iterator_wrapper* clone( + typename any_incrementable_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_incrementable_iterator_wrapper(m_it); + } + + virtual any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_incrementable_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_incrementable_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + private: + wrapped_type m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_single_pass_iterator_wrapper + : public any_single_pass_iterator_interface< + Reference + , Buffer + > + { + struct disabler {}; + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept )); + typedef any_single_pass_iterator_interface< + Reference, + Buffer + > base_type; + + public: + typedef typename base_type::reference reference; + + any_single_pass_iterator_wrapper() + : m_it() + {} + + explicit any_single_pass_iterator_wrapper(const WrappedIterator& it) + : m_it(it) + {} + // any_single_pass_iterator_interface implementation + virtual any_single_pass_iterator_wrapper* clone( + typename any_single_pass_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_single_pass_iterator_wrapper(m_it); + } + + virtual any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_single_pass_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_single_pass_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == range_detail::polymorphic_ref_downcast(other).m_it; + } + + virtual reference dereference() const + { + return dereference_cast(*m_it); + } + + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_forward_iterator_wrapper + : public any_forward_iterator_interface< + Reference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept )); + typedef any_forward_iterator_interface< + Reference, + Buffer + > base_type; + + public: + typedef typename base_type::reference reference; + + any_forward_iterator_wrapper() + : m_it() + {} + + explicit any_forward_iterator_wrapper(const WrappedIterator& it) + : m_it(it) + {} + + // any_forward_iterator_interface implementation + virtual any_forward_iterator_wrapper* clone( + typename any_forward_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_forward_iterator_wrapper(m_it); + } + + virtual any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_forward_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_forward_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == range_detail::polymorphic_ref_downcast(other).m_it; + } + + virtual reference dereference() const + { + return dereference_cast(*m_it); + } + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_bidirectional_iterator_wrapper + : public any_bidirectional_iterator_interface< + Reference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept )); + typedef any_bidirectional_iterator_interface< + Reference, + Buffer + > base_type; + + public: + typedef typename base_type::reference reference; + + any_bidirectional_iterator_wrapper() + : m_it() + { + } + + explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it) + : m_it(it) + { + } + + virtual any_bidirectional_iterator_wrapper* clone( + typename any_bidirectional_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_bidirectional_iterator_wrapper(*this); + } + + virtual any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_bidirectional_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_bidirectional_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual void decrement() + { + --m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == range_detail::polymorphic_ref_downcast(other).m_it; + } + + virtual reference dereference() const + { + return dereference_cast(*m_it); + } + + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + class any_random_access_iterator_wrapper + : public any_random_access_iterator_interface< + Reference + , Difference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept )); + typedef any_random_access_iterator_interface< + Reference, + Difference, + Buffer + > base_type; + + public: + typedef typename base_type::reference reference; + typedef Difference difference_type; + + any_random_access_iterator_wrapper() + : m_it() + { + } + + explicit any_random_access_iterator_wrapper(const WrappedIterator& other) + : m_it(other) + { + } + + virtual any_random_access_iterator_wrapper* clone( + typename any_random_access_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_random_access_iterator_wrapper(*this); + } + + virtual any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::const_reference + , Difference + , Buffer + >* clone_const_ref( + typename any_random_access_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::const_reference + , Difference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::reference_as_value_type + , Difference + , Buffer + >* clone_reference_as_value( + typename any_random_access_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::reference_as_value_type + , Difference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == range_detail::polymorphic_ref_downcast(other).m_it; + } + + virtual void decrement() + { + --m_it; + } + + virtual void advance(Difference offset) + { + m_it += offset; + } + + virtual reference dereference() const + { + return dereference_cast(*m_it); + } + + virtual Difference distance_to(const any_random_access_iterator_interface& other) const + { + return range_detail::polymorphic_ref_downcast(other).m_it - m_it; + } + + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Traversal + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , incrementable_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_incrementable_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , single_pass_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_single_pass_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , forward_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_forward_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , bidirectional_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_bidirectional_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , random_access_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_random_access_iterator_wrapper< + WrappedIterator + , Reference + , Difference + , Buffer + > type; + }; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/as_literal.hpp b/boost/range/detail/as_literal.hpp new file mode 100644 index 0000000..8b219ea --- /dev/null +++ b/boost/range/detail/as_literal.hpp @@ -0,0 +1,33 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_AS_LITERAL_HPP +#define BOOST_RANGE_DETAIL_AS_LITERAL_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost +{ + template< class Range > + inline iterator_range::type> + as_literal( Range& r ) + { + return ::boost::make_iterator_range( ::boost::range_detail::str_begin(r), + ::boost::range_detail::str_end(r) ); + } + +} + +#endif diff --git a/boost/range/detail/begin.hpp b/boost/range/detail/begin.hpp new file mode 100644 index 0000000..1d9390f --- /dev/null +++ b/boost/range/detail/begin.hpp @@ -0,0 +1,83 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_BEGIN_HPP +#define BOOST_RANGE_DETAIL_BEGIN_HPP + +#include // BOOST_MSVC +#include +#include +#include + +namespace boost +{ + + namespace range_detail + { + template< typename T > + struct range_begin; + + ////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_begin + { + template< typename C > + static BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type fun( C& c ) + { + return c.begin(); + }; + }; + + ////////////////////////////////////////////////////////////////////// + // pair + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_begin + { + template< typename P > + static BOOST_RANGE_DEDUCED_TYPENAME range_iterator

::type fun( const P& p ) + { + return p.first; + } + }; + + ////////////////////////////////////////////////////////////////////// + // array + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_begin + { + template + static BOOST_RANGE_DEDUCED_TYPENAME range_value::type* fun(T& t) + { + return t; + } + }; + + } // namespace 'range_detail' + + namespace range_adl_barrier + { + template< typename C > + inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + begin( C& c ) + { + return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); + } + } +} // namespace 'boost' + + +#endif diff --git a/boost/range/detail/collection_traits.hpp b/boost/range/detail/collection_traits.hpp new file mode 100644 index 0000000..c50ca3e --- /dev/null +++ b/boost/range/detail/collection_traits.hpp @@ -0,0 +1,266 @@ +// Boost string_algo library collection_traits.hpp header file -------------// + +// Copyright Pavol Droba 2002-2003. 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) + +// (C) Copyright Thorsten Ottosen 2002-2003. 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) + +// (C) Copyright Jeremy Siek 2001. 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) + +// Original idea of container traits was proposed by Jeremy Siek and +// Thorsten Ottosen. This implementation is lightweighted version +// of container_traits adapter for usage with string_algo library + +#ifndef BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP +#define BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP + +#include +#include +#include +#include + +// Implementation +#include + +/*! \file + Defines collection_traits class and related free-standing functions. + This facility is used to unify the access to different types of collections. + It allows the algorithms in the library to work with STL collections, c-style + array, null-terminated c-strings (and more) using the same interface. +*/ + +namespace boost { + namespace algorithm { + +// collection_traits template class -----------------------------------------// + + //! collection_traits class + /*! + Collection traits provide uniform access to different types of + collections. This functionality allows to write generic algorithms + which work with several different kinds of collections. + + Currently following collection types are supported: + - containers with STL compatible container interface ( see ContainerConcept ) + ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... ) + - c-style array + ( \c char[10], \c int[15] ... ) + - null-terminated c-strings + ( \c char*, \c wchar_T* ) + - std::pair of iterators + ( i.e \c std::pair::iterator,vector::iterator> ) + + Collection traits provide an external collection interface operations. + All are accessible using free-standing functions. + + The following operations are supported: + - \c size() + - \c empty() + - \c begin() + - \c end() + + Container traits have somewhat limited functionality on compilers not + supporting partial template specialization and partial template ordering. + */ + template< typename T > + struct collection_traits + { + private: + typedef BOOST_STRING_TYPENAME ::boost::mpl::eval_if< + ::boost::algorithm::detail::is_pair, + detail::pair_container_traits_selector, + BOOST_STRING_TYPENAME ::boost::mpl::eval_if< + ::boost::is_array, + detail::array_container_traits_selector, + BOOST_STRING_TYPENAME ::boost::mpl::eval_if< + ::boost::is_pointer, + detail::pointer_container_traits_selector, + detail::default_container_traits_selector + > + > + >::type container_helper_type; + public: + //! Function type + typedef container_helper_type function_type; + //! Value type + typedef BOOST_STRING_TYPENAME + container_helper_type::value_type value_type; + //! Size type + typedef BOOST_STRING_TYPENAME + container_helper_type::size_type size_type; + //! Iterator type + typedef BOOST_STRING_TYPENAME + container_helper_type::iterator iterator; + //! Const iterator type + typedef BOOST_STRING_TYPENAME + container_helper_type::const_iterator const_iterator; + //! Result iterator type ( iterator of const_iterator, depending on the constness of the container ) + typedef BOOST_STRING_TYPENAME + container_helper_type::result_iterator result_iterator; + //! Difference type + typedef BOOST_STRING_TYPENAME + container_helper_type::difference_type difference_type; + + }; // 'collection_traits' + +// collection_traits metafunctions -----------------------------------------// + + //! Container value_type trait + /*! + Extract the type of elements contained in a container + */ + template< typename C > + struct value_type_of + { + typedef BOOST_STRING_TYPENAME collection_traits::value_type type; + }; + + //! Container difference trait + /*! + Extract the container's difference type + */ + template< typename C > + struct difference_type_of + { + typedef BOOST_STRING_TYPENAME collection_traits::difference_type type; + }; + + //! Container iterator trait + /*! + Extract the container's iterator type + */ + template< typename C > + struct iterator_of + { + typedef BOOST_STRING_TYPENAME collection_traits::iterator type; + }; + + //! Container const_iterator trait + /*! + Extract the container's const_iterator type + */ + template< typename C > + struct const_iterator_of + { + typedef BOOST_STRING_TYPENAME collection_traits::const_iterator type; + }; + + + //! Container result_iterator + /*! + Extract the container's result_iterator type. This type maps to \c C::iterator + for mutable container and \c C::const_iterator for const containers. + */ + template< typename C > + struct result_iterator_of + { + typedef BOOST_STRING_TYPENAME collection_traits::result_iterator type; + }; + +// collection_traits related functions -----------------------------------------// + + //! Free-standing size() function + /*! + Get the size of the container. Uses collection_traits. + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::size_type + size( const C& c ) + { + return collection_traits::function_type::size( c ); + } + + //! Free-standing empty() function + /*! + Check whether the container is empty. Uses container traits. + */ + template< typename C > + inline bool empty( const C& c ) + { + return collection_traits::function_type::empty( c ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! Free-standing begin() function + /*! + Get the begin iterator of the container. Uses collection_traits. + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::iterator + begin( C& c ) + { + return collection_traits::function_type::begin( c ); + } + + //! Free-standing begin() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::const_iterator + begin( const C& c ) + { + return collection_traits::function_type::begin( c ); + } + + //! Free-standing end() function + /*! + Get the begin iterator of the container. Uses collection_traits. + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::iterator + end( C& c ) + { + return collection_traits::function_type::end( c ); + } + + //! Free-standing end() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::const_iterator + end( const C& c ) + { + return collection_traits::function_type::end( c ); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! Free-standing begin() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::result_iterator + begin( C& c ) + { + return collection_traits::function_type::begin( c ); + } + + //! Free-standing end() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::result_iterator + end( C& c ) + { + return collection_traits::function_type::end( c ); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_COLLECTION_TRAITS_HPP diff --git a/boost/range/detail/collection_traits_detail.hpp b/boost/range/detail/collection_traits_detail.hpp new file mode 100644 index 0000000..1f2b77c --- /dev/null +++ b/boost/range/detail/collection_traits_detail.hpp @@ -0,0 +1,501 @@ +// Boost string_algo library collection_traits.hpp header file -----------------------// + +// Copyright Pavol Droba 2002-2003. 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP +#define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Container traits implementation --------------------------------------------------------- + +namespace boost { + namespace algorithm { + namespace detail { + +// Default collection traits ----------------------------------------------------------------- + + // Default collection helper + /* + Wraps std::container compliant containers + */ + template< typename ContainerT > + struct default_container_traits + { + typedef BOOST_STRING_TYPENAME ContainerT::value_type value_type; + typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator; + typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME + ::boost::mpl::if_< ::boost::is_const, + const_iterator, + iterator + >::type result_iterator; + typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type; + typedef BOOST_STRING_TYPENAME ContainerT::size_type size_type; + + // static operations + template< typename C > + static size_type size( const C& c ) + { + return c.size(); + } + + template< typename C > + static bool empty( const C& c ) + { + return c.empty(); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename C > + static iterator begin( C& c ) + { + return c.begin(); + } + + template< typename C > + static const_iterator begin( const C& c ) + { + return c.begin(); + } + + template< typename C > + static iterator end( C& c ) + { + return c.end(); + } + + template< typename C > + static const_iterator end( const C& c ) + { + return c.end(); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename C > + static result_iterator begin( C& c ) + { + return c.begin(); + } + + template< typename C > + static result_iterator end( C& c ) + { + return c.end(); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + }; + + template + struct default_container_traits_selector + { + typedef default_container_traits type; + }; + +// Pair container traits --------------------------------------------------------------------- + + // pair selector + template< typename T, typename U > + yes_type is_pair_impl( const std::pair* ); + no_type is_pair_impl( ... ); + + template struct is_pair + { + private: + static T* t; + public: + BOOST_STATIC_CONSTANT( bool, value= + sizeof(is_pair_impl(t))==sizeof(yes_type) ); + }; + + // pair helper + template< typename PairT > + struct pair_container_traits + { + typedef BOOST_STRING_TYPENAME PairT::first_type element_type; + + typedef BOOST_STRING_TYPENAME ::boost::detail:: + iterator_traits::value_type value_type; + typedef std::size_t size_type; + typedef BOOST_STRING_TYPENAME ::boost::detail:: + iterator_traits::difference_type difference_type; + + typedef element_type iterator; + typedef element_type const_iterator; + typedef element_type result_iterator; + + // static operations + template< typename P > + static size_type size( const P& p ) + { + difference_type diff = std::distance( p.first, p.second ); + if ( diff < 0 ) + return 0; + else + return diff; + } + + template< typename P > + static bool empty( const P& p ) + { + return p.first==p.second; + } + + template< typename P > + static const_iterator begin( const P& p ) + { + return p.first; + } + + template< typename P > + static const_iterator end( const P& p ) + { + return p.second; + } + }; // 'pair_container_helper' + + template + struct pair_container_traits_selector + { + typedef pair_container_traits type; + }; + +// Array container traits --------------------------------------------------------------- + + // array traits ( partial specialization ) + template< typename T > + struct array_traits; + + template< typename T, std::size_t sz > + struct array_traits + { + // typedef + typedef T* iterator; + typedef const T* const_iterator; + typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // size of the array ( static ); + BOOST_STATIC_CONSTANT( size_type, array_size = sz ); + }; + + + // array length resolving + /* + Lenght of string contained in a static array could + be different from the size of the array. + For string processing we need the length without + terminating 0. + + Therefore, the length is calculated for char and wchar_t + using char_traits, rather then simply returning + the array size. + */ + template< typename T > + struct array_length_selector + { + template< typename TraitsT > + struct array_length + { + typedef BOOST_STRING_TYPENAME + TraitsT::size_type size_type; + + BOOST_STATIC_CONSTANT( + size_type, + array_size=TraitsT::array_size ); + + template< typename A > + static size_type length( const A& ) + { + return array_size; + } + + template< typename A > + static bool empty( const A& ) + { + return array_size==0; + } + }; + }; + + // specialization for char + template<> + struct array_length_selector + { + template< typename TraitsT > + struct array_length + { + typedef BOOST_STRING_TYPENAME + TraitsT::size_type size_type; + + template< typename A > + static size_type length( const A& a ) + { + if ( a==0 ) + return 0; + else + return std::char_traits::length(a); + } + + template< typename A > + static bool empty( const A& a ) + { + return a==0 || a[0]==0; + } + }; + }; + + // specialization for wchar_t + template<> + struct array_length_selector + { + template< typename TraitsT > + struct array_length + { + typedef BOOST_STRING_TYPENAME + TraitsT::size_type size_type; + + template< typename A > + static size_type length( const A& a ) + { + if ( a==0 ) + return 0; + else + return std::char_traits::length(a); + } + + template< typename A > + static bool empty( const A& a ) + { + return a==0 || a[0]==0; + } + }; + }; + + template< typename T > + struct array_container_traits + { + private: + // resolve array traits + typedef array_traits traits_type; + + public: + typedef BOOST_STRING_TYPENAME + traits_type::value_type value_type; + typedef BOOST_STRING_TYPENAME + traits_type::iterator iterator; + typedef BOOST_STRING_TYPENAME + traits_type::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME + traits_type::size_type size_type; + typedef BOOST_STRING_TYPENAME + traits_type::difference_type difference_type; + + typedef BOOST_STRING_TYPENAME + ::boost::mpl::if_< ::boost::is_const, + const_iterator, + iterator + >::type result_iterator; + + private: + // resolve array size + typedef BOOST_STRING_TYPENAME + ::boost::remove_cv::type char_type; + typedef BOOST_STRING_TYPENAME + array_length_selector:: + BOOST_NESTED_TEMPLATE array_length array_length_type; + + public: + BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size ); + + // static operations + template< typename A > + static size_type size( const A& a ) + { + return array_length_type::length(a); + } + + template< typename A > + static bool empty( const A& a ) + { + return array_length_type::empty(a); + } + + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename A > + static iterator begin( A& a ) + { + return a; + } + + template< typename A > + static const_iterator begin( const A& a ) + { + return a; + } + + template< typename A > + static iterator end( A& a ) + { + return a+array_length_type::length(a); + } + + template< typename A > + static const_iterator end( const A& a ) + { + return a+array_length_type::length(a); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename A > + static result_iterator begin( A& a ) + { + return a; + } + + template< typename A > + static result_iterator end( A& a ) + { + return a+array_length_type::length(a); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + }; + + template + struct array_container_traits_selector + { + typedef array_container_traits type; + }; + +// Pointer container traits --------------------------------------------------------------- + + template + struct pointer_container_traits + { + typedef BOOST_STRING_TYPENAME + ::boost::remove_pointer::type value_type; + + typedef BOOST_STRING_TYPENAME + ::boost::remove_cv::type char_type; + typedef ::std::char_traits char_traits; + + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; + + typedef BOOST_STRING_TYPENAME + ::boost::mpl::if_< ::boost::is_const, + const_iterator, + iterator + >::type result_iterator; + + // static operations + template< typename P > + static size_type size( const P& p ) + { + if ( p==0 ) + return 0; + else + return char_traits::length(p); + } + + template< typename P > + static bool empty( const P& p ) + { + return p==0 || p[0]==0; + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename P > + static iterator begin( P& p ) + { + return p; + } + + template< typename P > + static const_iterator begin( const P& p ) + { + return p; + } + + template< typename P > + static iterator end( P& p ) + { + if ( p==0 ) + return p; + else + return p+char_traits::length(p); + } + + template< typename P > + static const_iterator end( const P& p ) + { + if ( p==0 ) + return p; + else + return p+char_traits::length(p); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename P > + static result_iterator begin( P& p ) + { + return p; + } + + template< typename P > + static result_iterator end( P& p ) + { + if ( p==0 ) + return p; + else + return p+char_traits::length(p); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + }; + + template + struct pointer_container_traits_selector + { + typedef pointer_container_traits type; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_DETAIL_COLLECTION_HPP diff --git a/boost/range/detail/combine_cxx03.hpp b/boost/range/detail/combine_cxx03.hpp new file mode 100644 index 0000000..47da6a6 --- /dev/null +++ b/boost/range/detail/combine_cxx03.hpp @@ -0,0 +1,131 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP +#define BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP + +#ifndef BOOST_RANGE_MIN_COMBINE_ARGS +#define BOOST_RANGE_MIN_COMBINE_ARGS 2 +#endif + +#ifndef BOOST_RANGE_MAX_COMBINE_ARGS +#define BOOST_RANGE_MAX_COMBINE_ARGS 5 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +struct combined_result_impl; + +template +struct combined_result + : combined_result_impl::value> +{ +}; + +#define BOOST_RANGE_combined_element(z, n, data) \ + typename tuples::element::type + +#define BOOST_RANGE_combined_result(z, n, data) \ + template \ + struct combined_result_impl \ + : result_of \ + { \ + }; + +#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_result(~,n,~) + +#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \ + BOOST_RANGE_MAX_COMBINE_ARGS) +#include BOOST_PP_LOCAL_ITERATE() + +#define BOOST_RANGE_combined_get(z, n, data) get(tuple) + +#define BOOST_RANGE_combined_unpack(z, n, data) \ + template inline \ + typename combined_result::type \ + unpack_(mpl::int_, F f, const T& tuple) \ + { \ + return f(BOOST_PP_ENUM(n, BOOST_RANGE_combined_get, ~)); \ + } + +#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_unpack(~,n,~) +#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \ + BOOST_RANGE_MAX_COMBINE_ARGS) +#include BOOST_PP_LOCAL_ITERATE() + +} // namespace range_detail + +namespace range +{ + +#define BOOST_RANGE_combined_seq(z, n, data) boost::data(BOOST_PP_CAT(r,n)) + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include + +#else // by using rvalue references we avoid requiring 2^n overloads. + +#include + +#endif + +#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combine(~,n,~) +#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \ + BOOST_RANGE_MAX_COMBINE_ARGS) +#include BOOST_PP_LOCAL_ITERATE() + + } // namespace range + + using boost::range::combine; + +} // namespace boost + +#endif // include guard + +#undef BOOST_RANGE_combined_element +#undef BOOST_RANGE_combined_result +#undef BOOST_RANGE_combined_get +#undef BOOST_RANGE_combined_unpack +#undef BOOST_RANGE_combined_seq +#undef BOOST_RANGE_combined_exp_pred +#undef BOOST_RANGE_combined_exp_op +#undef BOOST_RANGE_combined_exp +#undef BOOST_RANGE_combined_bitset_pred +#undef BOOST_RANGE_combined_bitset_op +#undef BOOST_RANGE_combined_bitset +#undef BOOST_RANGE_combined_range_iterator +#undef BOOST_RANGE_combined_args +#undef BOOST_RANGE_combine_impl +#undef BOOST_RANGE_combine diff --git a/boost/range/detail/combine_cxx11.hpp b/boost/range/detail/combine_cxx11.hpp new file mode 100644 index 0000000..a7fa5b1 --- /dev/null +++ b/boost/range/detail/combine_cxx11.hpp @@ -0,0 +1,40 @@ +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP +#define BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP + +#include +#include +#include +#include +#include + +#include + +namespace boost +{ + namespace range + { + +template +auto combine(Ranges&&... rngs) -> + combined_range +{ + return combined_range( + boost::make_tuple(boost::begin(rngs)...), + boost::make_tuple(boost::end(rngs)...)); +} + + } // namespace range + +using range::combine; + +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/combine_no_rvalue.hpp b/boost/range/detail/combine_no_rvalue.hpp new file mode 100644 index 0000000..bdb3950 --- /dev/null +++ b/boost/range/detail/combine_no_rvalue.hpp @@ -0,0 +1,73 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#define BOOST_RANGE_combined_exp_pred(d, data) BOOST_PP_TUPLE_ELEM(3, 0, data) + +#define BOOST_RANGE_combined_exp_op(d, data) \ + ( \ + BOOST_PP_DEC( \ + BOOST_PP_TUPLE_ELEM(3, 0, data) \ + ), \ + BOOST_PP_TUPLE_ELEM(3, 1, data), \ + BOOST_PP_MUL_D( \ + d, \ + BOOST_PP_TUPLE_ELEM(3, 2, data), \ + BOOST_PP_TUPLE_ELEM(3, 1, data) \ + ) \ + ) + +#define BOOST_RANGE_combined_exp(x, n) \ + BOOST_PP_TUPLE_ELEM(3, 2, \ + BOOST_PP_WHILE(BOOST_RANGE_combined_exp_pred, \ + BOOST_RANGE_combined_exp_op, (n, x, 1))) + +#define BOOST_RANGE_combined_bitset_pred(n, state) \ + BOOST_PP_TUPLE_ELEM(2,1,state) + +#define BOOST_RANGE_combined_bitset_op(d, state) \ + (BOOST_PP_DIV_D(d, BOOST_PP_TUPLE_ELEM(2,0,state), 2), \ + BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2,1,state))) + +#define BOOST_RANGE_combined_bitset(i, n) \ +BOOST_PP_MOD(BOOST_PP_TUPLE_ELEM(2, 0, \ + BOOST_PP_WHILE(BOOST_RANGE_combined_bitset_pred, \ + BOOST_RANGE_combined_bitset_op, (i,n))), 2) + +#define BOOST_RANGE_combined_range_iterator(z, n, i) \ + typename range_iterator< \ + BOOST_PP_CAT(R,n) \ + BOOST_PP_IF( \ + BOOST_RANGE_combined_bitset(i,n), \ + BOOST_PP_IDENTITY(const), \ + BOOST_PP_EMPTY)() \ + >::type + +#define BOOST_RANGE_combined_args(z, n, i) \ + BOOST_PP_CAT(R, n) \ + BOOST_PP_IF(BOOST_RANGE_combined_bitset(i,n), const&, &) \ + BOOST_PP_CAT(r, n) + +#define BOOST_RANGE_combine_impl(z, i, n)\ + template \ + inline range::combined_range< \ + boost::tuple \ + > \ + combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, i)) \ + { \ + typedef tuple< \ + BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, i) \ + > rng_tuple_t; \ + return range::combined_range( \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \ + } + + +#define BOOST_RANGE_combine(z, n, data) \ + BOOST_PP_REPEAT(BOOST_RANGE_combined_exp(2,n), BOOST_RANGE_combine_impl, n) diff --git a/boost/range/detail/combine_rvalue.hpp b/boost/range/detail/combine_rvalue.hpp new file mode 100644 index 0000000..2e323b7 --- /dev/null +++ b/boost/range/detail/combine_rvalue.hpp @@ -0,0 +1,32 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#define BOOST_RANGE_combined_args(z, n, i) \ + BOOST_PP_CAT(R, n)&& BOOST_PP_CAT(r, n) + +#define BOOST_RANGE_combined_range_iterator(z, n, i) \ + typename range_iterator< \ + typename remove_reference::type \ + >::type + + +#define BOOST_RANGE_combine(z, n, data) \ + template \ + inline range::combined_range< \ + tuple \ + > \ + combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, ~)) \ + { \ + typedef tuple< \ + BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, ~) \ + > rng_tuple_t; \ + return range::combined_range( \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \ + } diff --git a/boost/range/detail/common.hpp b/boost/range/detail/common.hpp new file mode 100644 index 0000000..b0ad535 --- /dev/null +++ b/boost/range/detail/common.hpp @@ -0,0 +1,117 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_COMMON_HPP +#define BOOST_RANGE_DETAIL_COMMON_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// missing partial specialization workaround. +////////////////////////////////////////////////////////////////////////////// + +namespace boost +{ + namespace range_detail + { + // 1 = std containers + // 2 = std::pair + // 3 = const std::pair + // 4 = array + // 5 = const array + // 6 = char array + // 7 = wchar_t array + // 8 = char* + // 9 = const char* + // 10 = whar_t* + // 11 = const wchar_t* + // 12 = string + + typedef mpl::int_<1>::type std_container_; + typedef mpl::int_<2>::type std_pair_; + typedef mpl::int_<3>::type const_std_pair_; + typedef mpl::int_<4>::type array_; + typedef mpl::int_<5>::type const_array_; + typedef mpl::int_<6>::type char_array_; + typedef mpl::int_<7>::type wchar_t_array_; + typedef mpl::int_<8>::type char_ptr_; + typedef mpl::int_<9>::type const_char_ptr_; + typedef mpl::int_<10>::type wchar_t_ptr_; + typedef mpl::int_<11>::type const_wchar_t_ptr_; + typedef mpl::int_<12>::type string_; + + template< typename C > + struct range_helper + { + static C* c; + static C ptr; + + BOOST_STATIC_CONSTANT( bool, is_pair_ = sizeof( boost::range_detail::is_pair_impl( c ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_char_ptr_ = sizeof( boost::range_detail::is_char_ptr_impl( ptr ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_const_char_ptr_ = sizeof( boost::range_detail::is_const_char_ptr_impl( ptr ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_wchar_t_ptr_ = sizeof( boost::range_detail::is_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_ = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_char_array_ = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_ = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) ); + BOOST_STATIC_CONSTANT( bool, is_string_ = (boost::type_traits::ice_or::value )); + BOOST_STATIC_CONSTANT( bool, is_array_ = boost::is_array::value ); + + }; + + template< typename C > + class range + { + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_pair_, + boost::range_detail::std_pair_, + void >::type pair_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_array_, + boost::range_detail::array_, + pair_t >::type array_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_string_, + boost::range_detail::string_, + array_t >::type string_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_const_char_ptr_, + boost::range_detail::const_char_ptr_, + string_t >::type const_char_ptr_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_char_ptr_, + boost::range_detail::char_ptr_, + const_char_ptr_t >::type char_ptr_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_const_wchar_t_ptr_, + boost::range_detail::const_wchar_t_ptr_, + char_ptr_t >::type const_wchar_ptr_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_wchar_t_ptr_, + boost::range_detail::wchar_t_ptr_, + const_wchar_ptr_t >::type wchar_ptr_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_wchar_t_array_, + boost::range_detail::wchar_t_array_, + wchar_ptr_t >::type wchar_array_t; + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper::is_char_array_, + boost::range_detail::char_array_, + wchar_array_t >::type char_array_t; + public: + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::is_void::value, + boost::range_detail::std_container_, + char_array_t >::type type; + }; // class 'range' + } +} + +#endif + diff --git a/boost/range/detail/default_constructible_unary_fn.hpp b/boost/range/detail/default_constructible_unary_fn.hpp new file mode 100644 index 0000000..374ddda --- /dev/null +++ b/boost/range/detail/default_constructible_unary_fn.hpp @@ -0,0 +1,64 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class default_constructible_unary_fn_wrapper +{ +public: + typedef R result_type; + + default_constructible_unary_fn_wrapper() + { + } + default_constructible_unary_fn_wrapper(const F& source) + : m_impl(source) + { + } + template + R operator()(const Arg& arg) const + { + BOOST_ASSERT(m_impl); + return (*m_impl)(arg); + } + template + R operator()(Arg& arg) const + { + BOOST_ASSERT(m_impl); + return (*m_impl)(arg); + } +private: + boost::optional m_impl; +}; + +template +struct default_constructible_unary_fn_gen +{ + typedef typename boost::mpl::if_< + boost::has_trivial_default_constructor, + F, + default_constructible_unary_fn_wrapper + >::type type; +}; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/demote_iterator_traversal_tag.hpp b/boost/range/detail/demote_iterator_traversal_tag.hpp new file mode 100644 index 0000000..2127de9 --- /dev/null +++ b/boost/range/detail/demote_iterator_traversal_tag.hpp @@ -0,0 +1,91 @@ +// 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) +// +// Acknowledgements: +// aschoedl supplied a fix to supply the level of interoperability I had +// originally intended, but failed to implement. +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED + +#include + +namespace boost +{ + namespace range_detail + { + +template +struct inner_demote_iterator_traversal_tag +{ +}; + +#define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \ +template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \ +{ \ + typedef ResultTag type; \ +}; + +BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, no_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, incrementable_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, single_pass_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, forward_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, bidirectional_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, random_access_traversal_tag, no_traversal_tag ) + +BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, no_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, single_pass_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, forward_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, bidirectional_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, random_access_traversal_tag, incrementable_traversal_tag ) + +BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, no_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, forward_traversal_tag, single_pass_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, bidirectional_traversal_tag, single_pass_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, random_access_traversal_tag, single_pass_traversal_tag ) + +BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, no_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, forward_traversal_tag, forward_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, bidirectional_traversal_tag, forward_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, random_access_traversal_tag, forward_traversal_tag ) + +BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, no_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, forward_traversal_tag, forward_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, random_access_traversal_tag, bidirectional_traversal_tag ) + +BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, no_traversal_tag, no_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, forward_traversal_tag, forward_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag ) +BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal_tag, random_access_traversal_tag ) + +#undef BOOST_DEMOTE_TRAVERSAL_TAG + +template +struct demote_iterator_traversal_tag + : inner_demote_iterator_traversal_tag< + typename boost::detail::pure_traversal_tag< IteratorTraversalTag1 >::type, + typename boost::detail::pure_traversal_tag< IteratorTraversalTag2 >::type + > +{ +}; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/detail_str.hpp b/boost/range/detail/detail_str.hpp new file mode 100644 index 0000000..5ef7a34 --- /dev/null +++ b/boost/range/detail/detail_str.hpp @@ -0,0 +1,376 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_DETAIL_STR_HPP +#define BOOST_RANGE_DETAIL_DETAIL_STR_HPP + +#include // BOOST_MSVC +#include + +namespace boost +{ + + namespace range_detail + { + // + // iterator + // + + template<> + struct range_iterator_ + { + template< typename T > + struct pts + { + typedef BOOST_RANGE_DEDUCED_TYPENAME + remove_extent::type* type; + }; + }; + + template<> + struct range_iterator_ + { + template< typename S > + struct pts + { + typedef char* type; + }; + }; + + template<> + struct range_iterator_ + { + template< typename S > + struct pts + { + typedef const char* type; + }; + }; + + template<> + struct range_iterator_ + { + template< typename S > + struct pts + { + typedef wchar_t* type; + }; + }; + + template<> + struct range_iterator_ + { + template< typename S > + struct pts + { + typedef const wchar_t* type; + }; + }; + + + // + // const iterator + // + + template<> + struct range_const_iterator_ + { + template< typename T > + struct pts + { + typedef const BOOST_RANGE_DEDUCED_TYPENAME + remove_extent::type* type; + }; + }; + + template<> + struct range_const_iterator_ + { + template< typename S > + struct pts + { + typedef const char* type; + }; + }; + + template<> + struct range_const_iterator_ + { + template< typename S > + struct pts + { + typedef const char* type; + }; + }; + + template<> + struct range_const_iterator_ + { + template< typename S > + struct pts + { + typedef const wchar_t* type; + }; + }; + + template<> + struct range_const_iterator_ + { + template< typename S > + struct pts + { + typedef const wchar_t* type; + }; + }; + } +} + +#include +#include +#include +#include +#include + +namespace boost +{ + + namespace range_detail + { + // + // str_begin() + // + template<> + struct range_begin + { + static char* fun( char* s ) + { + return s; + } + }; + + template<> + struct range_begin + { + static const char* fun( const char* s ) + { + return s; + } + }; + + template<> + struct range_begin + { + + static wchar_t* fun( wchar_t* s ) + { + return s; + } + }; + + template<> + struct range_begin + { + static const wchar_t* fun( const wchar_t* s ) + { + return s; + } + }; + + template< typename C > + inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + str_begin( C& c ) + { + return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME + range_detail::range::type >::fun( c ); + } + + // + // str_end() + // + + template<> + struct range_end + { + template< typename T, std::size_t sz > + static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] ) + { + return boost::range_detail::array_end( boost_range_array ); + } + }; + + template<> + struct range_end + { + template< typename T, std::size_t sz > + static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] ) + { + return boost::range_detail::array_end( boost_range_array ); + } + }; + + template<> + struct range_end + { + static char* fun( char* s ) + { + return boost::range_detail::str_end( s ); + } + }; + + template<> + struct range_end + { + static const char* fun( const char* s ) + { + return boost::range_detail::str_end( s ); + } + }; + + template<> + struct range_end + { + static wchar_t* fun( wchar_t* s ) + { + return boost::range_detail::str_end( s ); + } + }; + + + template<> + struct range_end + { + static const wchar_t* fun( const wchar_t* s ) + { + return boost::range_detail::str_end( s ); + } + }; + + template< typename C > + inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + str_end( C& c ) + { + return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME + range_detail::range::type >::fun( c ); + } + + // + // size_type + // + + template<> + struct range_size_type_ + { + template< typename A > + struct pts + { + typedef std::size_t type; + }; + }; + + template<> + struct range_size_type_ + { + template< typename S > + struct pts + { + typedef std::size_t type; + }; + }; + + template<> + struct range_size_type_ + { + template< typename S > + struct pts + { + typedef std::size_t type; + }; + }; + + template<> + struct range_size_type_ + { + template< typename S > + struct pts + { + typedef std::size_t type; + }; + }; + + template<> + struct range_size_type_ + { + template< typename S > + struct pts + { + typedef std::size_t type; + }; + }; + + // + // value_type + // + + template<> + struct range_value_type_ + { + template< typename T > + struct pts + { + typedef char type; + }; + }; + + template<> + struct range_value_type_ + { + template< typename S > + struct pts + { + typedef char type; + }; + }; + + template<> + struct range_value_type_ + { + template< typename S > + struct pts + { + typedef const char type; + }; + }; + + template<> + struct range_value_type_ + { + template< typename S > + struct pts + { + typedef wchar_t type; + }; + }; + + template<> + struct range_value_type_ + { + template< typename S > + struct pts + { + typedef const wchar_t type; + }; + }; + + } // namespace 'range_detail' + +} // namespace 'boost' + + +#endif diff --git a/boost/range/detail/difference_type.hpp b/boost/range/detail/difference_type.hpp new file mode 100644 index 0000000..c641516 --- /dev/null +++ b/boost/range/detail/difference_type.hpp @@ -0,0 +1,121 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP +#define BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP + +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// missing partial specialization workaround. +////////////////////////////////////////////////////////////////////////////// + +namespace boost +{ + namespace range_detail + { + template< typename T > + struct range_difference_type_; + + template<> + struct range_difference_type_ + { + template< typename C > + struct pts + { + typedef BOOST_DEDUCED_TYPENAME C::difference_type type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename P > + struct pts + { + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename A > + struct pts + { + typedef std::ptrdiff_t type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename A > + struct pts + { + typedef std::ptrdiff_t type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename S > + struct pts + { + typedef std::ptrdiff_t type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename S > + struct pts + { + typedef std::ptrdiff_t type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename S > + struct pts + { + typedef std::ptrdiff_t type; + }; + }; + + template<> + struct range_difference_type_ + { + template< typename S > + struct pts + { + typedef std::ptrdiff_t type; + }; + }; + + } + + template< typename C > + class range_difference + { + typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type c_type; + public: + typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range_difference_type_::BOOST_NESTED_TEMPLATE pts::type type; + }; + +} + +#endif + diff --git a/boost/range/detail/empty.hpp b/boost/range/detail/empty.hpp new file mode 100644 index 0000000..b098705 --- /dev/null +++ b/boost/range/detail/empty.hpp @@ -0,0 +1,120 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_EMPTY_HPP +#define BOOST_RANGE_DETAIL_EMPTY_HPP + +#include + +namespace boost +{ + namespace range_detail + { + template< typename T > + struct range_empty; + + ////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_empty + { + template< typename C > + static bool fun( C& c ) + { + return c.empty(); + }; + }; + + ////////////////////////////////////////////////////////////////////// + // pair + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_empty + { + template< typename P > + static bool fun( const P& p ) + { + return p.first == p.second; + } + }; + + ////////////////////////////////////////////////////////////////////// + // array + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_empty + { + template< typename T, std::size_t sz > + static bool fun( T BOOST_ARRAY_REF[sz] ) + { + if( boost_range_array == 0 ) + return true; + return false; + } + }; + + ////////////////////////////////////////////////////////////////////// + // string + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_empty + { + static bool fun( const char* s ) + { + return s == 0 || s[0] == 0; + } + }; + + template<> + struct range_empty + { + static bool fun( const char* s ) + { + return s == 0 || s[0] == 0; + } + }; + + template<> + struct range_empty + { + static bool fun( const wchar_t* s ) + { + return s == 0 || s[0] == 0; + } + }; + + template<> + struct range_empty + { + static bool fun( const wchar_t* s ) + { + return s == 0 || s[0] == 0; + } + }; + + } // namespace 'range_detail' + + + template< typename C > + inline bool + empty( const C& c ) + { + return range_detail::range_empty< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); + } + +} // namespace 'boost' + + +#endif diff --git a/boost/range/detail/end.hpp b/boost/range/detail/end.hpp new file mode 100644 index 0000000..f2f7178 --- /dev/null +++ b/boost/range/detail/end.hpp @@ -0,0 +1,86 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_END_HPP +#define BOOST_RANGE_DETAIL_END_HPP + +#include // BOOST_MSVC +#include + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template< typename T > + struct range_end; + + ////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_end + { + template< typename C > + static BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + fun( C& c ) + { + return c.end(); + }; + }; + + ////////////////////////////////////////////////////////////////////// + // pair + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_end + { + template< typename P > + static BOOST_RANGE_DEDUCED_TYPENAME range_iterator

::type + fun( const P& p ) + { + return p.second; + } + }; + + ////////////////////////////////////////////////////////////////////// + // array + ////////////////////////////////////////////////////////////////////// + + template<> + struct range_end + { + template + static BOOST_RANGE_DEDUCED_TYPENAME remove_extent::type* fun(T& t) + { + return t + remove_extent::size; + } + }; + + } // namespace 'range_detail' + + namespace range_adl_barrier + { + template< typename C > + inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + end( C& c ) + { + return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); + } + } // namespace range_adl_barrier + +} // namespace 'boost' + +#endif diff --git a/boost/range/detail/extract_optional_type.hpp b/boost/range/detail/extract_optional_type.hpp new file mode 100644 index 0000000..0381434 --- /dev/null +++ b/boost/range/detail/extract_optional_type.hpp @@ -0,0 +1,48 @@ +// Boost.Range library +// +// Copyright Arno Schoedl & 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_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +#if !defined(BOOST_MPL_CFG_NO_HAS_XXX) + +// Defines extract_some_typedef which exposes T::some_typedef as +// extract_some_typedef::type if T::some_typedef exists. Otherwise +// extract_some_typedef is empty. +#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \ + BOOST_MPL_HAS_XXX_TRAIT_DEF(a_typedef) \ + template< typename C, bool B = BOOST_PP_CAT(has_, a_typedef)::value > \ + struct BOOST_PP_CAT(extract_, a_typedef) \ + {}; \ + template< typename C > \ + struct BOOST_PP_CAT(extract_, a_typedef)< C, true > \ + { \ + typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \ + }; + +#else + +#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \ + template< typename C > \ + struct BOOST_PP_CAT(extract_, a_typedef) \ + { \ + typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \ + }; + +#endif + +#endif // include guard diff --git a/boost/range/detail/has_member_size.hpp b/boost/range/detail/has_member_size.hpp new file mode 100644 index 0000000..0c639aa --- /dev/null +++ b/boost/range/detail/has_member_size.hpp @@ -0,0 +1,66 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_HAS_MEMBER_SIZE_HPP +#define BOOST_RANGE_DETAIL_HAS_MEMBER_SIZE_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class has_member_size_impl +{ +private: + template + class check + { + }; + + template + static boost::uint8_t f(check*); + + template + static boost::uint16_t f(...); + +public: + static const bool value = + (sizeof(f(0)) == sizeof(boost::uint8_t)); + + typedef typename mpl::if_c< + (sizeof(f(0)) == sizeof(boost::uint8_t)), + mpl::true_, + mpl::false_ + >::type type; +}; + +template +struct has_member_size +{ + typedef typename mpl::and_< + typename is_class::type, + typename has_member_size_impl::type + >::type type; + + static const bool value = + is_class::value && has_member_size_impl::value; +}; + + } // namespace range_detail +}// namespace boost + +#endif // include guard diff --git a/boost/range/detail/implementation_help.hpp b/boost/range/detail/implementation_help.hpp new file mode 100644 index 0000000..f35953f --- /dev/null +++ b/boost/range/detail/implementation_help.hpp @@ -0,0 +1,114 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP +#define BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP + +#include +#include +#include +#include +#include + +#ifndef BOOST_NO_CWCHAR +#include +#endif + +namespace boost +{ + namespace range_detail + { + template + inline void boost_range_silence_warning( const T& ) { } + + ///////////////////////////////////////////////////////////////////// + // end() help + ///////////////////////////////////////////////////////////////////// + + inline const char* str_end( const char* s, const char* ) + { + return s + strlen( s ); + } + +#ifndef BOOST_NO_CWCHAR + inline const wchar_t* str_end( const wchar_t* s, const wchar_t* ) + { + return s + wcslen( s ); + } +#else + inline const wchar_t* str_end( const wchar_t* s, const wchar_t* ) + { + if( s == 0 || s[0] == 0 ) + return s; + while( *++s != 0 ) + ; + return s; + } +#endif + + template< class Char > + inline Char* str_end( Char* s ) + { + return const_cast( str_end( s, s ) ); + } + + template< class T, std::size_t sz > + inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] ) + { + return boost_range_array + sz; + } + + template< class T, std::size_t sz > + inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] ) + { + return boost_range_array + sz; + } + + ///////////////////////////////////////////////////////////////////// + // size() help + ///////////////////////////////////////////////////////////////////// + + template< class Char > + inline std::size_t str_size( const Char* const& s ) + { + return str_end( s ) - s; + } + + template< class T, std::size_t sz > + inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] ) + { + boost_range_silence_warning( boost_range_array ); + return sz; + } + + template< class T, std::size_t sz > + inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] ) + { + boost_range_silence_warning( boost_range_array ); + return sz; + } + + inline bool is_same_address(const void* l, const void* r) + { + return l == r; + } + + template + inline bool is_same_object(const T1& l, const T2& r) + { + return range_detail::is_same_address(&l, &r); + } + + } // namespace 'range_detail' + +} // namespace 'boost' + + +#endif diff --git a/boost/range/detail/join_iterator.hpp b/boost/range/detail/join_iterator.hpp new file mode 100644 index 0000000..1020ebf --- /dev/null +++ b/boost/range/detail/join_iterator.hpp @@ -0,0 +1,354 @@ +// 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) +// +// Acknowledgements: +// aschoedl contributed an improvement to the determination +// of the Reference type parameter. +// +// Leonid Gershanovich reported Trac ticket 7376 about the dereference operator +// requiring identical reference types due to using the ternary if. +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +struct join_iterator_link +{ +public: + join_iterator_link(Iterator1 last1, Iterator2 first2) + : last1(last1) + , first2(first2) + { + } + + Iterator1 last1; + Iterator2 first2; + +private: + join_iterator_link() /* = delete */ ; +}; + +class join_iterator_begin_tag {}; +class join_iterator_end_tag {}; + +template +class join_iterator_union +{ +public: + typedef Iterator1 iterator1_t; + typedef Iterator2 iterator2_t; + + join_iterator_union() {} + join_iterator_union(unsigned int /*selected*/, const iterator1_t& it1, const iterator2_t& it2) : m_it1(it1), m_it2(it2) {} + + iterator1_t& it1() { return m_it1; } + const iterator1_t& it1() const { return m_it1; } + + iterator2_t& it2() { return m_it2; } + const iterator2_t& it2() const { return m_it2; } + + Reference dereference(unsigned int selected) const + { + if (selected) + return *m_it2; + return *m_it1; + } + + bool equal(const join_iterator_union& other, unsigned int selected) const + { + return selected + ? m_it2 == other.m_it2 + : m_it1 == other.m_it1; + } + +private: + iterator1_t m_it1; + iterator2_t m_it2; +}; + +template +class join_iterator_union +{ +public: + typedef Iterator iterator1_t; + typedef Iterator iterator2_t; + + join_iterator_union() {} + + join_iterator_union(unsigned int selected, const iterator1_t& it1, const iterator2_t& it2) + : m_it(selected ? it2 : it1) + { + } + + iterator1_t& it1() { return m_it; } + const iterator1_t& it1() const { return m_it; } + + iterator2_t& it2() { return m_it; } + const iterator2_t& it2() const { return m_it; } + + Reference dereference(unsigned int) const + { + return *m_it; + } + + bool equal(const join_iterator_union& other, + unsigned int /*selected*/) const + { + return m_it == other.m_it; + } + +private: + iterator1_t m_it; +}; + +template::type + // find least demanding, commonly supported reference type, in the order &, const&, and by-value: + , typename Reference = typename mpl::if_c< + !is_reference::type>::value + || !is_reference::type>::value, + typename remove_const< + typename remove_reference< + typename iterator_reference::type + >::type + >::type, + typename mpl::if_c< + is_const< + typename remove_reference< + typename iterator_reference::type + >::type + >::value + || is_const< + typename remove_reference< + typename iterator_reference::type + >::type + >::value, + typename add_const< + typename iterator_reference::type + >::type, + typename iterator_reference::type + >::type + >::type + , typename Traversal = typename demote_iterator_traversal_tag< + typename iterator_traversal::type + , typename iterator_traversal::type>::type +> +class join_iterator + : public iterator_facade, ValueType, Traversal, Reference> +{ + typedef join_iterator_link link_t; + typedef join_iterator_union iterator_union; +public: + typedef Iterator1 iterator1_t; + typedef Iterator2 iterator2_t; + + join_iterator() + : m_section(0u) + , m_it(0u, iterator1_t(), iterator2_t()) + , m_link(link_t(iterator1_t(), iterator2_t())) + {} + + join_iterator(unsigned int section, Iterator1 current1, Iterator1 last1, Iterator2 first2, Iterator2 current2) + : m_section(section) + , m_it(section, current1, current2) + , m_link(link_t(last1, first2)) + { + } + + template + join_iterator(Range1& r1, Range2& r2, join_iterator_begin_tag) + : m_section(boost::empty(r1) ? 1u : 0u) + , m_it(boost::empty(r1) ? 1u : 0u, boost::begin(r1), boost::begin(r2)) + , m_link(link_t(boost::end(r1), boost::begin(r2))) + { + } + + template + join_iterator(const Range1& r1, const Range2& r2, join_iterator_begin_tag) + : m_section(boost::empty(r1) ? 1u : 0u) + , m_it(boost::empty(r1) ? 1u : 0u, boost::const_begin(r1), boost::const_begin(r2)) + , m_link(link_t(boost::const_end(r1), boost::const_begin(r2))) + { + } + + template + join_iterator(Range1& r1, Range2& r2, join_iterator_end_tag) + : m_section(1u) + , m_it(1u, boost::end(r1), boost::end(r2)) + , m_link(link_t(boost::end(r1), boost::begin(r2))) + { + } + + template + join_iterator(const Range1& r1, const Range2& r2, join_iterator_end_tag) + : m_section(1u) + , m_it(1u, boost::const_end(r1), boost::const_end(r2)) + , m_link(link_t(boost::const_end(r1), boost::const_begin(r2))) + { + } + +private: + void increment() + { + if (m_section) + ++m_it.it2(); + else + { + ++m_it.it1(); + if (m_it.it1() == m_link.last1) + { + m_it.it2() = m_link.first2; + m_section = 1u; + } + } + } + + void decrement() + { + if (m_section) + { + if (m_it.it2() == m_link.first2) + { + m_it.it1() = boost::prior(m_link.last1); + m_section = 0u; + } + else + --m_it.it2(); + } + else + --m_it.it1(); + } + + typename join_iterator::reference dereference() const + { + return m_it.dereference(m_section); + } + + bool equal(const join_iterator& other) const + { + return m_section == other.m_section + && m_it.equal(other.m_it, m_section); + } + + void advance(typename join_iterator::difference_type offset) + { + if (m_section) + advance_from_range2(offset); + else + advance_from_range1(offset); + } + + typename join_iterator::difference_type distance_to(const join_iterator& other) const + { + typename join_iterator::difference_type result; + if (m_section) + { + if (other.m_section) + result = other.m_it.it2() - m_it.it2(); + else + { + result = (m_link.first2 - m_it.it2()) + + (other.m_it.it1() - m_link.last1); + + BOOST_ASSERT( result <= 0 ); + } + } + else + { + if (other.m_section) + { + result = (m_link.last1 - m_it.it1()) + + (other.m_it.it2() - m_link.first2); + } + else + result = other.m_it.it1() - m_it.it1(); + } + return result; + } + + void advance_from_range2(typename join_iterator::difference_type offset) + { + typedef typename join_iterator::difference_type difference_t; + BOOST_ASSERT( m_section == 1u ); + if (offset < 0) + { + difference_t r2_dist = m_link.first2 - m_it.it2(); + BOOST_ASSERT( r2_dist <= 0 ); + if (offset >= r2_dist) + std::advance(m_it.it2(), offset); + else + { + difference_t r1_dist = offset - r2_dist; + BOOST_ASSERT( r1_dist <= 0 ); + m_it.it1() = m_link.last1 + r1_dist; + m_section = 0u; + } + } + else + std::advance(m_it.it2(), offset); + } + + void advance_from_range1(typename join_iterator::difference_type offset) + { + typedef typename join_iterator::difference_type difference_t; + BOOST_ASSERT( m_section == 0u ); + if (offset > 0) + { + difference_t r1_dist = m_link.last1 - m_it.it1(); + BOOST_ASSERT( r1_dist >= 0 ); + if (offset < r1_dist) + std::advance(m_it.it1(), offset); + else + { + difference_t r2_dist = offset - r1_dist; + BOOST_ASSERT( r2_dist >= 0 ); + m_it.it2() = m_link.first2 + r2_dist; + m_section = 1u; + } + } + else + std::advance(m_it.it1(), offset); + } + + unsigned int m_section; + iterator_union m_it; + link_t m_link; + + friend class ::boost::iterator_core_access; +}; + + } // namespace range_detail + +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/microsoft.hpp b/boost/range/detail/microsoft.hpp new file mode 100644 index 0000000..7b672c9 --- /dev/null +++ b/boost/range/detail/microsoft.hpp @@ -0,0 +1,931 @@ +#ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP +#define BOOST_RANGE_DETAIL_MICROSOFT_HPP + +// Boost.Range MFC/ATL Extension +// +// Copyright Shunsuke Sogame 2005-2006. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + + +// config +// + + +#include + + +#define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1 + + +#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) + #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator + #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin + #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end +#else + #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator + #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin + #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end +#endif + + + + +// yet another customization way +// + + +#include // iterator_difference +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // disable_if + +#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) + #include +#else + #include // distance + #include + #include + #include +#endif + + +namespace boost { namespace range_detail_microsoft { + + + // customization point + // + + template< class Tag > + struct customization; + + + template< class T > + struct customization_tag; + + + struct using_type_as_tag + { }; + + + // Topic: + // In fact, it is unnecessary for VC++. + // VC++'s behavior seems conforming, while GCC fails without this. + template< class Iterator, class T > + struct mutable_ : + disable_if< is_const, Iterator > + { }; + + + // helpers + // + + template< class Tag, class T > + struct customization_tag_of + { + typedef typename mpl::if_< is_same, + T, + Tag + >::type type; + }; + + + template< class T > + struct customization_of + { + typedef typename remove_cv::type bare_t; + typedef typename customization_tag::type tag_t; + typedef customization type; + }; + + + template< class T > + struct mutable_iterator_of + { + typedef typename remove_cv::type bare_t; + typedef typename customization_of::type cust_t; + typedef typename cust_t::template meta::mutable_iterator type; + }; + + + template< class T > + struct const_iterator_of + { + typedef typename remove_cv::type bare_t; + typedef typename customization_of::type cust_t; + typedef typename cust_t::template meta::const_iterator type; + }; + + + template< class T > + struct size_type_of + { + typedef typename range_detail_microsoft::mutable_iterator_of::type miter_t; + typedef typename iterator_difference::type type; + }; + + + template< class T > inline + typename mutable_iterator_of::type + begin_of(T& x) + { + typedef typename customization_of::type cust_t; + return cust_t().template begin::type>(x); + } + + + template< class T > inline + typename const_iterator_of::type + begin_of(T const& x) + { + typedef typename customization_of::type cust_t; + return cust_t().template begin::type>(x); + } + + + template< class T > inline + typename mutable_iterator_of::type + end_of(T& x) + { + typedef typename customization_of::type cust_t; + return cust_t().template end::type>(x); + } + + + template< class T > inline + typename const_iterator_of::type + end_of(T const& x) + { + typedef typename customization_of::type cust_t; + return cust_t().template end::type>(x); + } + + +#if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) + + template< class T > inline + typename size_type_of::type + size_of(T const& x) + { + return std::distance(boost::begin(x), boost::end(x)); + } + +#endif + + + template< class Range > + struct compatible_mutable_iterator : + BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator + { }; + + +} } // namespace boost::range_detail_microsoft + + +#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \ + BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \ +/**/ + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \ + namespace elem { \ + /**/ + + +#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \ + BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \ +/**/ + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \ + } \ + /**/ + + +#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \ + :: elem \ +/**/ + + +#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \ + namespace boost { namespace range_detail_microsoft { \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + } } \ + \ + namespace boost { \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + } \ + \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \ +/**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \ + BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \ + template< > \ + struct customization_tag< Fullname > : \ + customization_tag_of< Tag, Fullname > \ + { }; \ + /**/ + + + // metafunctions + // + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \ + template< > \ + struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \ + range_detail_microsoft::mutable_iterator_of< Fullname > \ + { }; \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \ + template< > \ + struct range_const_iterator< Fullname > : \ + range_detail_microsoft::const_iterator_of< Fullname > \ + { }; \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \ + template< > \ + struct range_size< Fullname > : \ + range_detail_microsoft::size_type_of< Fullname > \ + { }; \ + /**/ + + + // functions + // + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \ + inline \ + boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \ + { \ + return boost::range_detail_microsoft::begin_of(x); \ + } \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \ + inline \ + boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \ + { \ + return boost::range_detail_microsoft::begin_of(x); \ + } \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \ + inline \ + boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \ + { \ + return boost::range_detail_microsoft::end_of(x); \ + } \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \ + inline \ + boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \ + { \ + return boost::range_detail_microsoft::end_of(x); \ + } \ + /**/ + + + #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \ + /**/ + + #else + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \ + inline \ + boost::range_detail_microsoft::size_type_of< Fullname >::type \ + boost_range_size(Fullname const& x) \ + { \ + return boost::range_detail_microsoft::size_of(x); \ + } \ + /**/ + + #endif + + +#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \ + Tag, NamespaceList, Name, \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \ + ) \ +/**/ + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \ + BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \ + ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \ + BOOST_PP_REPEAT \ + )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \ + /**/ + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \ + (class) \ + /**/ + + +#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \ + namespace boost { namespace range_detail_microsoft { \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \ + Tag, \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + } } \ + \ + namespace boost { \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + } \ + \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + ) \ + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \ +/**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \ + /**/ + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \ + BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ + BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \ + :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \ + template< Params > \ + struct customization_tag< Fullname > : \ + customization_tag_of< Tag, Fullname > \ + { }; \ + /**/ + + + // metafunctions + // + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \ + template< Params > \ + struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \ + range_detail_microsoft::mutable_iterator_of< Fullname > \ + { }; \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \ + template< Params > \ + struct range_const_iterator< Fullname > : \ + range_detail_microsoft::const_iterator_of< Fullname > \ + { }; \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \ + template< Params > \ + struct range_size< Fullname > : \ + range_detail_microsoft::size_type_of< Fullname > \ + { }; \ + /**/ + + + // functions + // + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \ + template< Params > inline \ + typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \ + { \ + return boost::range_detail_microsoft::begin_of(x); \ + } \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \ + template< Params > inline \ + typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \ + { \ + return boost::range_detail_microsoft::begin_of(x); \ + } \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \ + template< Params > inline \ + typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \ + { \ + return boost::range_detail_microsoft::end_of(x); \ + } \ + /**/ + + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \ + template< Params > inline \ + typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ + BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \ + { \ + return boost::range_detail_microsoft::end_of(x); \ + } \ + /**/ + + + #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \ + /**/ + + #else + + #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \ + template< Params > inline \ + typename boost::range_detail_microsoft::size_type_of< Fullname >::type \ + boost_range_size(Fullname const& x) \ + { \ + return boost::range_detail_microsoft::size_of(x); \ + } \ + /**/ + + #endif + + + + +// list_iterator and helpers +// + + +#include +#include +#include +#include +#include + + +// POSITION's header is undocumented, so is NULL. +// +struct __POSITION; // incomplete, but used as just a pointer. +typedef __POSITION *POSITION; + + +namespace boost { namespace range_detail_microsoft { + + + template< + class ListT, + class Value, + class Reference, + class Traversal + > + struct list_iterator; + + + template< + class ListT, + class Value, + class Reference, + class Traversal + > + struct list_iterator_super + { + typedef typename mpl::if_< is_same, + Value&, + Reference + >::type ref_t; + + typedef typename mpl::if_< is_same, + bidirectional_traversal_tag, + Traversal + >::type trv_t; + + typedef iterator_facade< + list_iterator, + Value, + trv_t, + ref_t + > type; + }; + + + template< + class ListT, + class Value, + class Reference = use_default, + class Traversal = use_default + > + struct list_iterator : + list_iterator_super::type + { + private: + typedef list_iterator self_t; + typedef typename list_iterator_super::type super_t; + typedef typename super_t::reference ref_t; + + public: + explicit list_iterator() + { } + + explicit list_iterator(ListT& lst, POSITION pos) : + m_plst(boost::addressof(lst)), m_pos(pos) + { } + + template< class, class, class, class > friend struct list_iterator; + template< class ListT_, class Value_, class Reference_, class Traversal_> + list_iterator(list_iterator const& other) : + m_plst(other.m_plst), m_pos(other.m_pos) + { } + + private: + ListT *m_plst; + POSITION m_pos; + + friend class iterator_core_access; + ref_t dereference() const + { + BOOST_ASSERT(m_pos != 0 && "out of range"); + return m_plst->GetAt(m_pos); + } + + // A B C D x + // Head Tail NULL(0) + // + void increment() + { + BOOST_ASSERT(m_pos != 0 && "out of range"); + m_plst->GetNext(m_pos); + } + + void decrement() + { + if (m_pos == 0) { + m_pos = m_plst->GetTailPosition(); + return; + } + + m_plst->GetPrev(m_pos); + } + + bool equal(self_t const& other) const + { + BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible"); + return m_pos == other.m_pos; + } + }; + + + // customization helpers + // + + struct array_functions + { + template< class Iterator, class X > + Iterator begin(X& x) + { + return x.GetData(); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return begin(x) + x.GetSize(); + } + }; + + + struct list_functions + { + template< class Iterator, class X > + Iterator begin(X& x) + { + return Iterator(x, x.GetHeadPosition()); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return Iterator(x, POSITION(0)); + } + }; + + +} } // namespace boost::range_detail_microsoft + + + + +// test +// + + +#if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST) + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace range_detail_microsoft { + + + template< class Range1, class Range2 > + bool test_equals(Range1 const& rng1, Range2 const& rng2) + { + return + boost::distance(rng1) == boost::distance(rng2) && + std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2)) + ; + } + + + template< class AssocContainer, class PairT > + bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa) + { + typedef typename boost::range_const_iterator::type iter_t; + for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) { + if (it->first == pa.first && it->second == pa.second) + return true; + } + + return false; + } + + + // test functions + // + + template< class Range > + bool test_emptiness(Range& ) + { + bool result = true; + + Range emptyRng; + result = result && boost::empty(emptyRng); + + return result; + } + + + template< class Range > + bool test_trivial(Range& rng) + { + bool result = true; + + // convertibility check + typedef typename range_const_iterator::type citer_t; + citer_t cit = boost::begin(rng); + (void)cit; // unused + + // mutability check + typedef typename range_value::type val_t; + val_t v = *boost::begin(rng); + *boost::begin(rng) = v; + result = result && *boost::begin(rng) == v; + + return result; + } + + + template< class Range > + bool test_forward(Range& rng) + { + boost::function_requires< ForwardRangeConcept >(); + + bool result = (test_trivial)(rng); + + typedef typename range_value::type val_t; + + std::vector saved; + std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved)); + std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved)); + + std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng)); + + return result && (test_equals)(saved, rng); + }; + + + template< class Range > + bool test_bidirectional(Range& rng) + { + boost::function_requires< BidirectionalRangeConcept >(); + + bool result = (test_forward)(rng); + + typedef typename range_value::type val_t; + + std::vector saved; + std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved)); + + result = result && (test_equals)( + boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)), + boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng)) + ); + + return result; + } + + + template< class Range > + bool test_random_access(Range& rng) + { + boost::function_requires< RandomAccessRangeConcept >(); + + bool result = (test_bidirectional)(rng); + + typedef typename range_value::type val_t; + + std::vector saved; + std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved)); + std::sort(boost::begin(saved), boost::end(saved)); + + std::random_shuffle(boost::begin(rng), boost::end(rng)); + std::sort(boost::begin(rng), boost::end(rng)); + result = result && (test_equals)(rng, saved); + + std::random_shuffle(boost::begin(rng), boost::end(rng)); + std::stable_sort(boost::begin(rng), boost::end(rng)); + result = result && (test_equals)(rng, saved); + + std::random_shuffle(boost::begin(rng), boost::end(rng)); + std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng)); + result = result && (test_equals)(rng, saved); + + return result; + } + + + // initializer + // + + template< class ArrayT, class SampleRange > + bool test_init_array(ArrayT& arr, SampleRange const& sample) + { + typedef typename range_const_iterator::type iter_t; + typedef typename range_value::type val_t; + + for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { + val_t v = *it; // works around ATL3 CSimpleArray + arr.Add(v); + } + + return (test_equals)(arr, sample); + } + + + template< class ListT, class SampleRange > + bool test_init_list(ListT& lst, SampleRange const& sample) + { + typedef typename range_const_iterator::type iter_t; + + for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { + lst.AddTail(*it); + } + + return (test_equals)(lst, sample); + } + + + template< class StringT, class SampleRange > + bool test_init_string(StringT& str, SampleRange const& sample) + { + typedef typename range_const_iterator::type iter_t; + typedef typename range_value::type val_t; + + for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { + str += *it; + } + + return (test_equals)(str, sample); + } + + + template< class MapT, class SampleMap > + bool test_init_map(MapT& map, SampleMap const& sample) + { + typedef typename range_const_iterator::type iter_t; + + for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { + map.SetAt(it->first, it->second); + } + + return boost::distance(map) == boost::distance(sample); + } + + + // metafunction test + // + + template< class Range, class Iter > + struct test_mutable_iter : + boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator::type, Iter > + { }; + + + template< class Range, class Iter > + struct test_const_iter : + boost::is_same< typename boost::range_const_iterator::type, Iter > + { }; + + +} } // namespace boost::range_detail_microsoft + + +#endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST) + + + +#endif diff --git a/boost/range/detail/misc_concept.hpp b/boost/range/detail/misc_concept.hpp new file mode 100644 index 0000000..74cb919 --- /dev/null +++ b/boost/range/detail/misc_concept.hpp @@ -0,0 +1,33 @@ +// Boost.Range library concept checks +// +// Copyright Neil Groves 2009. Use, modification and distribution +// are subject to the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +#ifndef BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED + +#include + +namespace boost +{ + namespace range_detail + { + template + class SameTypeConcept + { + public: + BOOST_CONCEPT_USAGE(SameTypeConcept) + { + same_type(a,b); + } + private: + template void same_type(T,T) {} + T1 a; + T2 b; + }; + } +} + +#endif // include guard diff --git a/boost/range/detail/msvc_has_iterator_workaround.hpp b/boost/range/detail/msvc_has_iterator_workaround.hpp new file mode 100644 index 0000000..62b67fd --- /dev/null +++ b/boost/range/detail/msvc_has_iterator_workaround.hpp @@ -0,0 +1,132 @@ +// Boost.Range library +// +// Copyright Eric Niebler 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_MSVC_HAS_ITERATOR_WORKAROUND_HPP +#define BOOST_RANGE_DETAIL_MSVC_HAS_ITERATOR_WORKAROUND_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#ifndef BOOST_RANGE_MUTABLE_ITERATOR_HPP +# error This file should only be included from +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600) +namespace boost +{ +namespace cb_details +{ + template + struct iterator; +} + +namespace python +{ + template + struct iterator; +} + +namespace type_erasure +{ + template< + class Traversal, + class T /*= _self*/, + class Reference /*= ::boost::use_default*/, + class DifferenceType /*= ::std::ptrdiff_t*/, + class ValueType /*= typename deduced >::type*/ + > + struct iterator; +} + +namespace unordered { namespace iterator_detail +{ + template + struct iterator; +}} + +namespace container { namespace container_detail +{ + template + class iterator; +}} + +namespace spirit { namespace lex { namespace lexertl +{ + template + class iterator; +}}} + +namespace range_detail +{ + template + struct has_iterator< ::boost::cb_details::iterator > + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::cb_details::iterator const> + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::python::iterator > + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::python::iterator const> + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::type_erasure::iterator > + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::type_erasure::iterator const> + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::unordered::iterator_detail::iterator > + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::unordered::iterator_detail::iterator const> + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::container::container_detail::iterator > + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::container::container_detail::iterator const> + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::spirit::lex::lexertl::iterator > + : mpl::false_ + {}; + + template + struct has_iterator< ::boost::spirit::lex::lexertl::iterator const> + : mpl::false_ + {}; +} +} +#endif +#endif diff --git a/boost/range/detail/range_return.hpp b/boost/range/detail/range_return.hpp new file mode 100644 index 0000000..773a72a --- /dev/null +++ b/boost/range/detail/range_return.hpp @@ -0,0 +1,180 @@ +// 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_DETAIL_RANGE_RETURN_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ + enum range_return_value + { + // (*) indicates the most common values + return_found, // only the found resulting iterator (*) + return_next, // next(found) iterator + return_prior, // prior(found) iterator + return_begin_found, // [begin, found) range (*) + return_begin_next, // [begin, next(found)) range + return_begin_prior, // [begin, prior(found)) range + return_found_end, // [found, end) range (*) + return_next_end, // [next(found), end) range + return_prior_end, // [prior(found), end) range + return_begin_end // [begin, end) range + }; + + template< class SinglePassRange, range_return_value > + struct range_return + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + SinglePassRange& rng) + { + return type(found, boost::end(rng)); + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_found > + { + typedef BOOST_DEDUCED_TYPENAME range_iterator::type type; + + static type pack(type found, SinglePassRange&) + { + return found; + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_next > + { + typedef BOOST_DEDUCED_TYPENAME range_iterator::type type; + + static type pack(type found, SinglePassRange& rng) + { + return found == boost::end(rng) + ? found + : boost::next(found); + } + }; + + template< class BidirectionalRange > + struct range_return< BidirectionalRange, return_prior > + { + typedef BOOST_DEDUCED_TYPENAME range_iterator::type type; + + static type pack(type found, BidirectionalRange& rng) + { + return found == boost::begin(rng) + ? found + : boost::prior(found); + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_begin_found > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + SinglePassRange& rng) + { + return type(boost::begin(rng), found); + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_begin_next > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + SinglePassRange& rng) + { + return type( boost::begin(rng), + found == boost::end(rng) ? found : boost::next(found) ); + } + }; + + template< class BidirectionalRange > + struct range_return< BidirectionalRange, return_begin_prior > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + BidirectionalRange& rng) + { + return type( boost::begin(rng), + found == boost::begin(rng) ? found : boost::prior(found) ); + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_found_end > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + SinglePassRange& rng) + { + return type(found, boost::end(rng)); + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_next_end > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + SinglePassRange& rng) + { + return type( found == boost::end(rng) ? found : boost::next(found), + boost::end(rng) ); + } + }; + + template< class BidirectionalRange > + struct range_return< BidirectionalRange, return_prior_end > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type found, + BidirectionalRange& rng) + { + return type( found == boost::begin(rng) ? found : boost::prior(found), + boost::end(rng) ); + } + }; + + template< class SinglePassRange > + struct range_return< SinglePassRange, return_begin_end > + { + typedef boost::iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type > type; + + static type pack(BOOST_DEDUCED_TYPENAME range_iterator::type, + SinglePassRange& rng) + { + return type(boost::begin(rng), boost::end(rng)); + } + }; + +} + +#endif // include guard diff --git a/boost/range/detail/remove_extent.hpp b/boost/range/detail/remove_extent.hpp new file mode 100644 index 0000000..68e4597 --- /dev/null +++ b/boost/range/detail/remove_extent.hpp @@ -0,0 +1,157 @@ +// Boost.Range library +// +// Copyright Jonathan Turkanis 2005. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#ifndef BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP +#define BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP + +#include // MSVC, NO_INTRINSIC_WCHAR_T, put size_t in std. +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + + template< typename Case1 = mpl::true_, + typename Type1 = mpl::void_, + typename Case2 = mpl::true_, + typename Type2 = mpl::void_, + typename Case3 = mpl::true_, + typename Type3 = mpl::void_, + typename Case4 = mpl::true_, + typename Type4 = mpl::void_, + typename Case5 = mpl::true_, + typename Type5 = mpl::void_, + typename Case6 = mpl::true_, + typename Type6 = mpl::void_, + typename Case7 = mpl::true_, + typename Type7 = mpl::void_, + typename Case8 = mpl::true_, + typename Type8 = mpl::void_, + typename Case9 = mpl::true_, + typename Type9 = mpl::void_, + typename Case10 = mpl::true_, + typename Type10 = mpl::void_, + typename Case11 = mpl::true_, + typename Type11 = mpl::void_, + typename Case12 = mpl::true_, + typename Type12 = mpl::void_, + typename Case13 = mpl::true_, + typename Type13 = mpl::void_, + typename Case14 = mpl::true_, + typename Type14 = mpl::void_, + typename Case15 = mpl::true_, + typename Type15 = mpl::void_, + typename Case16 = mpl::true_, + typename Type16 = mpl::void_, + typename Case17 = mpl::true_, + typename Type17 = mpl::void_, + typename Case18 = mpl::true_, + typename Type18 = mpl::void_, + typename Case19 = mpl::true_, + typename Type19 = mpl::void_, + typename Case20 = mpl::true_, + typename Type20 = mpl::void_> + struct select { + typedef typename + mpl::eval_if< + Case1, mpl::identity, mpl::eval_if< + Case2, mpl::identity, mpl::eval_if< + Case3, mpl::identity, mpl::eval_if< + Case4, mpl::identity, mpl::eval_if< + Case5, mpl::identity, mpl::eval_if< + Case6, mpl::identity, mpl::eval_if< + Case7, mpl::identity, mpl::eval_if< + Case8, mpl::identity, mpl::eval_if< + Case9, mpl::identity, mpl::if_< + Case10, Type10, mpl::void_ > > > > > > > > > + >::type result1; + typedef typename + mpl::eval_if< + Case11, mpl::identity, mpl::eval_if< + Case12, mpl::identity, mpl::eval_if< + Case13, mpl::identity, mpl::eval_if< + Case14, mpl::identity, mpl::eval_if< + Case15, mpl::identity, mpl::eval_if< + Case16, mpl::identity, mpl::eval_if< + Case17, mpl::identity, mpl::eval_if< + Case18, mpl::identity, mpl::eval_if< + Case19, mpl::identity, mpl::if_< + Case20, Type20, mpl::void_ > > > > > > > > > + > result2; + typedef typename + mpl::eval_if< + is_same, + result2, + mpl::identity + >::type type; + }; + + template + struct remove_extent { + static T* ar; + BOOST_STATIC_CONSTANT(std::size_t, size = sizeof(*ar) / sizeof((*ar)[0])); + + typedef typename + select< + is_same, bool, + is_same, char, + is_same, signed char, + is_same, unsigned char, + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + is_same, wchar_t, + #endif + is_same, short, + is_same, unsigned short, + is_same, int, + is_same, unsigned int, + is_same, long, + is_same, unsigned long, + is_same, float, + is_same, double, + is_same, long double + >::type result1; + typedef typename + select< + is_same, const bool, + is_same, const char, + is_same, const signed char, + is_same, const unsigned char, + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + is_same, const wchar_t, + #endif + is_same, const short, + is_same, const unsigned short, + is_same, const int, + is_same, const unsigned int, + is_same, const long, + is_same, const unsigned long, + is_same, const float, + is_same, const double, + is_same, const long double + > result2; + typedef typename + mpl::eval_if< + is_same, + result2, + mpl::identity + >::type type; + }; + + } // namespace 'range_detail' + +} // namespace 'boost' + + +#endif diff --git a/boost/range/detail/safe_bool.hpp b/boost/range/detail/safe_bool.hpp new file mode 100644 index 0000000..182e510 --- /dev/null +++ b/boost/range/detail/safe_bool.hpp @@ -0,0 +1,72 @@ +// This header intentionally has no include guards. +// +// Copyright (c) 2010 Neil Groves +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// This code utilises the experience gained during the evolution of +// +#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP +#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP + +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class safe_bool +{ +public: + typedef safe_bool this_type; + +#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_) + typedef bool unspecified_bool_type; + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x; + } +#elif defined(_MANAGED) + static void unspecified_bool(this_type***) + { + } + typedef void(*unspecified_bool_type)(this_type***); + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x ? unspecified_bool : 0; + } +#elif \ + ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ + ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ + ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) + + typedef bool (this_type::*unspecified_bool_type)() const; + + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x ? &this_type::detail_safe_bool_member_fn : 0; + } +private: + bool detail_safe_bool_member_fn() const { return false; } +#else + typedef DataMemberPtr unspecified_bool_type; + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p) + { + return x ? p : 0; + } +#endif +private: + safe_bool(); + safe_bool(const safe_bool&); + void operator=(const safe_bool&); + ~safe_bool(); +}; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/boost/range/detail/sfinae.hpp b/boost/range/detail/sfinae.hpp new file mode 100644 index 0000000..5b2c61e --- /dev/null +++ b/boost/range/detail/sfinae.hpp @@ -0,0 +1,77 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_SFINAE_HPP +#define BOOST_RANGE_DETAIL_SFINAE_HPP + +#include +#include +#include +#include + + +namespace boost +{ + namespace range_detail + { + using type_traits::yes_type; + using type_traits::no_type; + + ////////////////////////////////////////////////////////////////////// + // string + ////////////////////////////////////////////////////////////////////// + + yes_type is_string_impl( const char* const ); + yes_type is_string_impl( const wchar_t* const ); + no_type is_string_impl( ... ); + + template< std::size_t sz > + yes_type is_char_array_impl( char BOOST_RANGE_ARRAY_REF()[sz] ); + template< std::size_t sz > + yes_type is_char_array_impl( const char BOOST_RANGE_ARRAY_REF()[sz] ); + no_type is_char_array_impl( ... ); + + template< std::size_t sz > + yes_type is_wchar_t_array_impl( wchar_t BOOST_RANGE_ARRAY_REF()[sz] ); + template< std::size_t sz > + yes_type is_wchar_t_array_impl( const wchar_t BOOST_RANGE_ARRAY_REF()[sz] ); + no_type is_wchar_t_array_impl( ... ); + + yes_type is_char_ptr_impl( char* const ); + no_type is_char_ptr_impl( ... ); + + yes_type is_const_char_ptr_impl( const char* const ); + no_type is_const_char_ptr_impl( ... ); + + yes_type is_wchar_t_ptr_impl( wchar_t* const ); + no_type is_wchar_t_ptr_impl( ... ); + + yes_type is_const_wchar_t_ptr_impl( const wchar_t* const ); + no_type is_const_wchar_t_ptr_impl( ... ); + + ////////////////////////////////////////////////////////////////////// + // pair + ////////////////////////////////////////////////////////////////////// + + template< typename Iterator > + yes_type is_pair_impl( const std::pair* ); + no_type is_pair_impl( ... ); + + ////////////////////////////////////////////////////////////////////// + // tags + ////////////////////////////////////////////////////////////////////// + + struct char_or_wchar_t_array_tag {}; + + } // namespace 'range_detail' + +} // namespace 'boost' + +#endif diff --git a/boost/range/detail/size_type.hpp b/boost/range/detail/size_type.hpp new file mode 100644 index 0000000..78a60a4 --- /dev/null +++ b/boost/range/detail/size_type.hpp @@ -0,0 +1,55 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_SIZE_TYPE_HPP +#define BOOST_RANGE_DETAIL_SIZE_TYPE_HPP + +#include + +////////////////////////////////////////////////////////////////////////////// +// missing partial specialization workaround. +////////////////////////////////////////////////////////////////////////////// + +namespace boost +{ + namespace range_detail + { + template< typename T > + struct range_size_type_ + { + template< typename C > + struct pts + { + typedef std::size_t type; + }; + }; + + template<> + struct range_size_type_ + { + template< typename C > + struct pts + { + typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type; + }; + }; + } + + template< typename C > + class range_size + { + typedef typename range_detail::range::type c_type; + public: + typedef typename range_detail::range_size_type_::BOOST_NESTED_TEMPLATE pts::type type; + }; +} + +#endif + diff --git a/boost/range/detail/sizer.hpp b/boost/range/detail/sizer.hpp new file mode 100644 index 0000000..cd6679c --- /dev/null +++ b/boost/range/detail/sizer.hpp @@ -0,0 +1,35 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_SIZER_HPP +#define BOOST_RANGE_DETAIL_SIZER_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost +{ + ////////////////////////////////////////////////////////////////////// + // constant array size + ////////////////////////////////////////////////////////////////////// + + template< typename T, std::size_t sz > + char (& sizer( const T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz]; + + template< typename T, std::size_t sz > + char (& sizer( T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz]; + +} // namespace 'boost' + +#endif diff --git a/boost/range/detail/str_types.hpp b/boost/range/detail/str_types.hpp new file mode 100644 index 0000000..f8cab19 --- /dev/null +++ b/boost/range/detail/str_types.hpp @@ -0,0 +1,38 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_STR_TYPES_HPP +#define BOOST_RANGE_DETAIL_STR_TYPES_HPP + +#include +#include + +namespace boost +{ + template< class T > + struct range_mutable_iterator + { + typedef T* type; + }; + + template< class T > + struct range_const_iterator + { + typedef const T* type; + }; + + template< class T > + struct range_size + { + typedef std::size_t type; + }; +} + +#endif diff --git a/boost/range/detail/value_type.hpp b/boost/range/detail/value_type.hpp new file mode 100644 index 0000000..2784514 --- /dev/null +++ b/boost/range/detail/value_type.hpp @@ -0,0 +1,72 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DETAIL_VALUE_TYPE_HPP +#define BOOST_RANGE_DETAIL_VALUE_TYPE_HPP + +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// missing partial specialization workaround. +////////////////////////////////////////////////////////////////////////////// + +namespace boost +{ + namespace range_detail + { + template< typename T > + struct range_value_type_; + + template<> + struct range_value_type_ + { + template< typename C > + struct pts + { + typedef BOOST_RANGE_DEDUCED_TYPENAME C::value_type type; + }; + }; + + template<> + struct range_value_type_ + { + template< typename P > + struct pts + { + typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_value< BOOST_RANGE_DEDUCED_TYPENAME P::first_type >::type type; + }; + }; + + template<> + struct range_value_type_ + { + template< typename T > + struct pts + { + typedef BOOST_DEDUCED_TYPENAME remove_extent::type type; + }; + }; + + } + + template< typename C > + class range_value + { + typedef BOOST_DEDUCED_TYPENAME range_detail::range::type c_type; + public: + typedef BOOST_DEDUCED_TYPENAME range_detail::range_value_type_::BOOST_NESTED_TEMPLATE pts::type type; + }; + +} + +#endif + diff --git a/boost/range/difference_type.hpp b/boost/range/difference_type.hpp new file mode 100644 index 0000000..afd8b07 --- /dev/null +++ b/boost/range/difference_type.hpp @@ -0,0 +1,35 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DIFFERENCE_TYPE_HPP +#define BOOST_RANGE_DIFFERENCE_TYPE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost +{ + template< class T > + struct range_difference + : iterator_difference< + BOOST_DEDUCED_TYPENAME range_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type + >::type + > + { }; +} + +#endif diff --git a/boost/range/distance.hpp b/boost/range/distance.hpp new file mode 100644 index 0000000..075f2d1 --- /dev/null +++ b/boost/range/distance.hpp @@ -0,0 +1,34 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_DISTANCE_HPP +#define BOOST_RANGE_DISTANCE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + + template< class T > + inline BOOST_DEDUCED_TYPENAME range_difference::type + distance( const T& r ) + { + return std::distance( boost::begin( r ), boost::end( r ) ); + } + +} // namespace 'boost' + +#endif diff --git a/boost/range/empty.hpp b/boost/range/empty.hpp new file mode 100644 index 0000000..d57a30e --- /dev/null +++ b/boost/range/empty.hpp @@ -0,0 +1,34 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_EMPTY_HPP +#define BOOST_RANGE_EMPTY_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + + template< class T > + inline bool empty( const T& r ) + { + return boost::begin( r ) == boost::end( r ); + } + +} // namespace 'boost' + + +#endif diff --git a/boost/range/end.hpp b/boost/range/end.hpp new file mode 100644 index 0000000..f2a3337 --- /dev/null +++ b/boost/range/end.hpp @@ -0,0 +1,128 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_END_HPP +#define BOOST_RANGE_END_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +#include +#else + +#include +#include +#include + +namespace boost +{ + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +namespace range_detail +{ +#endif + + ////////////////////////////////////////////////////////////////////// + // primary template + ////////////////////////////////////////////////////////////////////// + template< typename C > + inline BOOST_DEDUCED_TYPENAME range_iterator::type + range_end( C& c ) + { + // + // If you get a compile-error here, it is most likely because + // you have not implemented range_begin() properly in + // the namespace of C + // + return c.end(); + } + + ////////////////////////////////////////////////////////////////////// + // pair + ////////////////////////////////////////////////////////////////////// + + template< typename Iterator > + inline Iterator range_end( const std::pair& p ) + { + return p.second; + } + + template< typename Iterator > + inline Iterator range_end( std::pair& p ) + { + return p.second; + } + + ////////////////////////////////////////////////////////////////////// + // array + ////////////////////////////////////////////////////////////////////// + + template< typename T, std::size_t sz > + inline const T* range_end( const T (&a)[sz] ) + { + return range_detail::array_end( a ); + } + + template< typename T, std::size_t sz > + inline T* range_end( T (&a)[sz] ) + { + return range_detail::array_end( a ); + } + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +} // namespace 'range_detail' +#endif + +namespace range_adl_barrier +{ + +template< class T > +inline BOOST_DEDUCED_TYPENAME range_iterator::type end( T& r ) +{ +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + using namespace range_detail; +#endif + return range_end( r ); +} + +template< class T > +inline BOOST_DEDUCED_TYPENAME range_iterator::type end( const T& r ) +{ +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + using namespace range_detail; +#endif + return range_end( r ); +} + + } // namespace range_adl_barrier +} // namespace 'boost' + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +namespace boost +{ + namespace range_adl_barrier + { + template< class T > + inline BOOST_DEDUCED_TYPENAME range_iterator::type + const_end( const T& r ) + { + return boost::range_adl_barrier::end( r ); + } + } // namespace range_adl_barrier + using namespace range_adl_barrier; +} // namespace boost + +#endif + diff --git a/boost/range/functions.hpp b/boost/range/functions.hpp new file mode 100644 index 0000000..43c54b1 --- /dev/null +++ b/boost/range/functions.hpp @@ -0,0 +1,27 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_FUNCTIONS_HPP +#define BOOST_RANGE_FUNCTIONS_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/boost/range/has_range_iterator.hpp b/boost/range/has_range_iterator.hpp new file mode 100644 index 0000000..9eb58b3 --- /dev/null +++ b/boost/range/has_range_iterator.hpp @@ -0,0 +1,83 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +// Acknowledgments: +// Ticket #8341: Arno Schoedl - improved handling of has_range_iterator upon +// use-cases where T was const. +#ifndef BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED +#define BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(type) + + template + struct has_range_iterator_impl + : boost::mpl::false_ + { + }; + + template + struct has_range_iterator_impl< + T, + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + BOOST_DEDUCED_TYPENAME mpl::eval_if, + has_type::type> >, + has_type > + >::type + >::type + > + : boost::mpl::true_ + { + }; + + template + struct has_range_const_iterator_impl + : boost::mpl::false_ + { + }; + + template + struct has_range_const_iterator_impl< + T, + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + has_type > + >::type + > + : boost::mpl::true_ + { + }; + + } // namespace range_detail + + template + struct has_range_iterator + : range_detail::has_range_iterator_impl< + BOOST_DEDUCED_TYPENAME remove_reference::type> + {}; + + template + struct has_range_const_iterator + : range_detail::has_range_const_iterator_impl< + BOOST_DEDUCED_TYPENAME remove_reference::type> + {}; +} // namespace boost + +#endif // include guard + diff --git a/boost/range/irange.hpp b/boost/range/irange.hpp new file mode 100644 index 0000000..b1a1240 --- /dev/null +++ b/boost/range/irange.hpp @@ -0,0 +1,236 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_IRANGE_HPP_INCLUDED +#define BOOST_RANGE_IRANGE_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // integer_iterator is an iterator over an integer sequence that + // is bounded only by the limits of the underlying integer + // representation. + // + // This is useful for implementing the irange(first, last) + // function. + // + // Note: + // This use of this iterator and irange is appreciably less + // performant than the corresponding hand-written integer + // loop on many compilers. + template + class integer_iterator + : public boost::iterator_facade< + integer_iterator, + Integer, + boost::random_access_traversal_tag, + Integer, + std::ptrdiff_t + > + { + typedef boost::iterator_facade< + integer_iterator, + Integer, + boost::random_access_traversal_tag, + Integer, + std::ptrdiff_t + > base_t; + public: + typedef typename base_t::value_type value_type; + typedef typename base_t::difference_type difference_type; + typedef typename base_t::reference reference; + typedef std::random_access_iterator_tag iterator_category; + + integer_iterator() : m_value() {} + explicit integer_iterator(value_type x) : m_value(x) {} + + private: + void increment() + { + ++m_value; + } + + void decrement() + { + --m_value; + } + + void advance(difference_type offset) + { + m_value += offset; + } + + difference_type distance_to(const integer_iterator& other) const + { + return is_signed::value + ? (other.m_value - m_value) + : (other.m_value >= m_value) + ? static_cast(other.m_value - m_value) + : -static_cast(m_value - other.m_value); + } + + bool equal(const integer_iterator& other) const + { + return m_value == other.m_value; + } + + reference dereference() const + { + return m_value; + } + + friend class ::boost::iterator_core_access; + value_type m_value; + }; + + // integer_iterator_with_step is similar in nature to the + // integer_iterator but provides the ability to 'move' in + // a number of steps specified at construction time. + // + // The three variable implementation provides the best guarantees + // of loop termination upon various combinations of input. + // + // While this design is less performant than some less + // safe alternatives, the use of ranges and iterators to + // perform counting will never be optimal anyhow, hence + // if optimal performance is desired a hand-coded loop + // is the solution. + template + class integer_iterator_with_step + : public boost::iterator_facade< + integer_iterator_with_step, + Integer, + boost::random_access_traversal_tag, + Integer, + std::ptrdiff_t + > + { + typedef boost::iterator_facade< + integer_iterator_with_step, + Integer, + boost::random_access_traversal_tag, + Integer, + std::ptrdiff_t + > base_t; + public: + typedef typename base_t::value_type value_type; + typedef typename base_t::difference_type difference_type; + typedef typename base_t::reference reference; + typedef std::random_access_iterator_tag iterator_category; + + integer_iterator_with_step(value_type first, difference_type step, value_type step_size) + : m_first(first) + , m_step(step) + , m_step_size(step_size) + { + } + + private: + void increment() + { + ++m_step; + } + + void decrement() + { + --m_step; + } + + void advance(difference_type offset) + { + m_step += offset; + } + + difference_type distance_to(const integer_iterator_with_step& other) const + { + return other.m_step - m_step; + } + + bool equal(const integer_iterator_with_step& other) const + { + return m_step == other.m_step; + } + + reference dereference() const + { + return m_first + (m_step * m_step_size); + } + + friend class ::boost::iterator_core_access; + value_type m_first; + difference_type m_step; + difference_type m_step_size; + }; + + } // namespace range_detail + + template + class integer_range + : public iterator_range< range_detail::integer_iterator > + { + typedef range_detail::integer_iterator iterator_t; + typedef iterator_range base_t; + public: + integer_range(Integer first, Integer last) + : base_t(iterator_t(first), iterator_t(last)) + { + } + }; + + template + class strided_integer_range + : public iterator_range< range_detail::integer_iterator_with_step > + { + typedef range_detail::integer_iterator_with_step iterator_t; + typedef iterator_range base_t; + public: + template + strided_integer_range(Iterator first, Iterator last) + : base_t(first, last) + { + } + }; + + template + integer_range + irange(Integer first, Integer last) + { + BOOST_ASSERT( first <= last ); + return integer_range(first, last); + } + + template + strided_integer_range + irange(Integer first, Integer last, StepSize step_size) + { + BOOST_ASSERT( step_size != 0 ); + BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) ); + + typedef typename range_detail::integer_iterator_with_step iterator_t; + + const std::ptrdiff_t sz = static_cast(step_size >= 0 ? step_size : -step_size); + const Integer l = step_size >= 0 ? last : first; + const Integer f = step_size >= 0 ? first : last; + const std::ptrdiff_t num_steps = (l - f) / sz + ((l - f) % sz ? 1 : 0); + BOOST_ASSERT(num_steps >= 0); + + return strided_integer_range( + iterator_t(first, 0, step_size), + iterator_t(first, num_steps, step_size)); + } + +} // namespace boost + +#endif // include guard diff --git a/boost/range/istream_range.hpp b/boost/range/istream_range.hpp new file mode 100644 index 0000000..a486317 --- /dev/null +++ b/boost/range/istream_range.hpp @@ -0,0 +1,37 @@ +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED +#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED + +/*! + * \file istream_range.hpp + */ + +#include +#include +#include +#include + +namespace boost +{ + namespace range + { + template inline + iterator_range > + istream_range(std::basic_istream& in) + { + return iterator_range >( + std::istream_iterator(in), + std::istream_iterator()); + } + } // namespace range + using range::istream_range; +} // namespace boost + +#endif // include guard diff --git a/boost/range/iterator.hpp b/boost/range/iterator.hpp new file mode 100644 index 0000000..f15bf3b --- /dev/null +++ b/boost/range/iterator.hpp @@ -0,0 +1,76 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ITERATOR_HPP +#define BOOST_RANGE_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + + namespace range_detail_vc7_1 + { + template< typename C, typename Sig = void(C) > + struct range_iterator + { + typedef BOOST_RANGE_DEDUCED_TYPENAME + mpl::eval_if_c< is_const::value, + range_const_iterator< typename remove_const::type >, + range_mutable_iterator >::type type; + }; + + template< typename C, typename T > + struct range_iterator< C, void(T[]) > + { + typedef T* type; + }; + } + +#endif + + template< typename C, typename Enabler=void > + struct range_iterator + { +#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + + typedef BOOST_RANGE_DEDUCED_TYPENAME + range_detail_vc7_1::range_iterator::type type; + +#else + + private: + typedef typename remove_reference::type param_t; + + public: + typedef typename mpl::eval_if_c< + is_const::value, + range_const_iterator::type>, + range_mutable_iterator + >::type type; + +#endif + }; + +} // namespace boost + +#endif diff --git a/boost/range/iterator_range.hpp b/boost/range/iterator_range.hpp new file mode 100644 index 0000000..dfcd4d2 --- /dev/null +++ b/boost/range/iterator_range.hpp @@ -0,0 +1,16 @@ +// 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_ITERATOR_RANGE_HPP_INCLUDED +#define BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED + +#include "boost/range/iterator_range_core.hpp" +#include "boost/range/iterator_range_io.hpp" + +#endif // include guard diff --git a/boost/range/iterator_range_core.hpp b/boost/range/iterator_range_core.hpp new file mode 100644 index 0000000..8108947 --- /dev/null +++ b/boost/range/iterator_range_core.hpp @@ -0,0 +1,869 @@ +// Boost.Range library +// +// Copyright Neil Groves & Thorsten Ottosen & Pavol Droba 2003-2004. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +// Credits: +// 'michel' reported Trac 9072 which included a patch for allowing references +// to function types. +// +#ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED +#define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED + +#include // Define __STL_CONFIG_H, if appropriate. +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) + #pragma warning( push ) + #pragma warning( disable : 4996 ) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! \file + Defines the \c iterator_class and related functions. + \c iterator_range is a simple wrapper of iterator pair idiom. It provides + a rich subset of Container interface. +*/ + + +namespace boost +{ + namespace iterator_range_detail + { + // + // The functions adl_begin and adl_end are implemented in a separate + // class for gcc-2.9x + // + template + struct iterator_range_impl { + template< class ForwardRange > + static IteratorT adl_begin( ForwardRange& r ) + { + return static_cast( boost::begin( r ) ); + } + + template< class ForwardRange > + static IteratorT adl_end( ForwardRange& r ) + { + return static_cast( boost::end( r ) ); + } + }; + + template< class Left, class Right > + inline bool less_than( const Left& l, const Right& r ) + { + return std::lexicographical_compare( boost::begin(l), + boost::end(l), + boost::begin(r), + boost::end(r) ); + } + + template< class Left, class Right > + inline bool greater_than( const Left& l, const Right& r ) + { + return iterator_range_detail::less_than(r,l); + } + + template< class Left, class Right > + inline bool less_or_equal_than( const Left& l, const Right& r ) + { + return !iterator_range_detail::less_than(r,l); + } + + template< class Left, class Right > + inline bool greater_or_equal_than( const Left& l, const Right& r ) + { + return !iterator_range_detail::less_than(l,r); + } + + // This version is maintained since it is used in other boost libraries + // such as Boost.Assign + template< class Left, class Right > + inline bool equal(const Left& l, const Right& r) + { + return boost::equal(l, r); + } + +struct range_tag +{ +}; + +struct const_range_tag +{ +}; + +struct iterator_range_tag +{ +}; + +typedef char (&incrementable_t)[1]; +typedef char (&bidirectional_t)[2]; +typedef char (&random_access_t)[3]; + +incrementable_t test_traversal_tag(boost::incrementable_traversal_tag); +bidirectional_t test_traversal_tag(boost::bidirectional_traversal_tag); +random_access_t test_traversal_tag(boost::random_access_traversal_tag); + +template +struct pure_iterator_traversal_impl +{ + typedef boost::incrementable_traversal_tag type; +}; + +template<> +struct pure_iterator_traversal_impl +{ + typedef boost::bidirectional_traversal_tag type; +}; + +template<> +struct pure_iterator_traversal_impl +{ + typedef boost::random_access_traversal_tag type; +}; + +template +struct pure_iterator_traversal +{ + typedef + BOOST_DEDUCED_TYPENAME iterator_traversal::type + traversal_t; + BOOST_STATIC_CONSTANT( + std::size_t, + traversal_i = sizeof(iterator_range_detail::test_traversal_tag((traversal_t()))) + ); + typedef + BOOST_DEDUCED_TYPENAME pure_iterator_traversal_impl::type + type; +}; + +template +class iterator_range_base + : public iterator_range_tag +{ + typedef range_detail::safe_bool< + IteratorT iterator_range_base::* + > safe_bool_t; + + typedef iterator_range_base type; + +protected: + typedef iterator_range_impl impl; + +public: + typedef BOOST_DEDUCED_TYPENAME + safe_bool_t::unspecified_bool_type unspecified_bool_type; + + typedef BOOST_DEDUCED_TYPENAME + iterator_value::type value_type; + + typedef BOOST_DEDUCED_TYPENAME + iterator_difference::type difference_type; + + typedef std::size_t size_type; // note: must be unsigned + + // Needed because value-type is the same for + // const and non-const iterators + typedef BOOST_DEDUCED_TYPENAME + iterator_reference::type reference; + + //! const_iterator type + /*! + There is no distinction between const_iterator and iterator. + These typedefs are provides to fulfill container interface + */ + typedef IteratorT const_iterator; + //! iterator type + typedef IteratorT iterator; + +protected: + iterator_range_base() + : m_Begin() + , m_End() + { + } + + template + iterator_range_base(Iterator Begin, Iterator End) + : m_Begin(Begin) + , m_End(End) + { + } + +public: + IteratorT begin() const + { + return m_Begin; + } + + IteratorT end() const + { + return m_End; + } + + bool empty() const + { + return m_Begin == m_End; + } + + operator unspecified_bool_type() const + { + return safe_bool_t::to_unspecified_bool( + m_Begin != m_End, &iterator_range_base::m_Begin); + } + + bool operator!() const + { + return empty(); + } + + bool equal(const iterator_range_base& r) const + { + return m_Begin == r.m_Begin && m_End == r.m_End; + } + + reference front() const + { + BOOST_ASSERT(!empty()); + return *m_Begin; + } + + void drop_front() + { + BOOST_ASSERT(!empty()); + ++m_Begin; + } + + void drop_front(difference_type n) + { + BOOST_ASSERT(n >= difference_type()); + std::advance(this->m_Begin, n); + } + + // Deprecated + void pop_front() { drop_front(); } + +protected: + template + void assign(Iterator first, Iterator last) + { + m_Begin = first; + m_End = last; + } + + template + void assign(const SinglePassRange& r) + { + m_Begin = impl::adl_begin(r); + m_End = impl::adl_end(r); + } + + template + void assign(SinglePassRange& r) + { + m_Begin = impl::adl_begin(r); + m_End = impl::adl_end(r); + } + + IteratorT m_Begin; + IteratorT m_End; +}; + +template +class iterator_range_base + : public iterator_range_base +{ + typedef iterator_range_base base_type; + +protected: + iterator_range_base() + { + } + + template + iterator_range_base(Iterator first, Iterator last) + : base_type(first, last) + { + } + +public: + typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type; + typedef BOOST_DEDUCED_TYPENAME base_type::reference reference; + + reference back() const + { + BOOST_ASSERT(!this->empty()); + return *boost::prior(this->m_End); + } + + void drop_back() + { + BOOST_ASSERT(!this->empty()); + --this->m_End; + } + + void drop_back(difference_type n) + { + BOOST_ASSERT(n >= difference_type()); + std::advance(this->m_End, -n); + } + + // Deprecated + void pop_back() { drop_back(); } +}; + +template +class iterator_range_base + : public iterator_range_base +{ + typedef iterator_range_base< + IteratorT, bidirectional_traversal_tag> base_type; + +public: + typedef BOOST_DEDUCED_TYPENAME + boost::mpl::if_< + boost::mpl::or_< + boost::is_abstract< + BOOST_DEDUCED_TYPENAME base_type::value_type + >, + boost::is_array< + BOOST_DEDUCED_TYPENAME base_type::value_type + >, + boost::is_function< + BOOST_DEDUCED_TYPENAME base_type::value_type + > + >, + BOOST_DEDUCED_TYPENAME base_type::reference, + BOOST_DEDUCED_TYPENAME base_type::value_type + >::type abstract_value_type; + + // Rationale: + // typedef these here to reduce verbiage in the implementation of this + // type. + typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type; + typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type; + typedef BOOST_DEDUCED_TYPENAME base_type::reference reference; + +protected: + iterator_range_base() + { + } + + template + iterator_range_base(Iterator first, Iterator last) + : base_type(first, last) + { + } + +public: + reference operator[](difference_type at) const + { + BOOST_ASSERT(at >= 0); + BOOST_ASSERT(static_cast(at) < size()); + return this->m_Begin[at]; + } + + // + // When storing transform iterators, operator[]() + // fails because it returns by reference. Therefore + // operator()() is provided for these cases. + // + abstract_value_type operator()(difference_type at) const + { + BOOST_ASSERT(at >= 0); + BOOST_ASSERT(static_cast(at) < size()); + return this->m_Begin[at]; + } + + BOOST_DEDUCED_TYPENAME base_type::size_type size() const + { + return this->m_End - this->m_Begin; + } +}; + + } + +// iterator range template class -----------------------------------------// + + //! iterator_range class + /*! + An \c iterator_range delimits a range in a sequence by beginning and ending iterators. + An iterator_range can be passed to an algorithm which requires a sequence as an input. + For example, the \c toupper() function may be used most frequently on strings, + but can also be used on iterator_ranges: + + \code + boost::tolower( find( s, "UPPERCASE STRING" ) ); + \endcode + + Many algorithms working with sequences take a pair of iterators, + delimiting a working range, as an arguments. The \c iterator_range class is an + encapsulation of a range identified by a pair of iterators. + It provides a collection interface, + so it is possible to pass an instance to an algorithm requiring a collection as an input. + */ + template + class iterator_range + : public iterator_range_detail::iterator_range_base< + IteratorT, + BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal::type + > + { + typedef iterator_range_detail::iterator_range_base< + IteratorT, + BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal::type + > base_type; + + template + struct is_compatible_range + : is_convertible< + BOOST_DEDUCED_TYPENAME mpl::eval_if< + has_range_iterator, + range_iterator, + mpl::identity + >::type, + BOOST_DEDUCED_TYPENAME base_type::iterator + > + { + }; + + protected: + typedef iterator_range_detail::iterator_range_impl impl; + + public: + typedef iterator_range type; + + iterator_range() + { + } + + template + iterator_range(Iterator first, Iterator last) + : base_type(first, last) + { + } + + template + iterator_range( + const SinglePassRange& r, + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + is_compatible_range + >::type* = 0 + ) + : base_type(impl::adl_begin(r), impl::adl_end(r)) + { + } + + template + iterator_range( + SinglePassRange& r, + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + is_compatible_range + >::type* = 0 + ) + : base_type(impl::adl_begin(r), impl::adl_end(r)) + { + } + + template + iterator_range(const SinglePassRange& r, + iterator_range_detail::const_range_tag) + : base_type(impl::adl_begin(r), impl::adl_end(r)) + { + } + + template + iterator_range(SinglePassRange& r, + iterator_range_detail::range_tag) + : base_type(impl::adl_begin(r), impl::adl_end(r)) + { + } + + template + iterator_range& operator=(const iterator_range& other) + { + this->assign(other.begin(), other.end()); + return *this; + } + + template + iterator_range& operator=(iterator_range& other) + { + this->assign(other.begin(), other.end()); + return *this; + } + + template + iterator_range& operator=(SinglePassRange& r) + { + this->assign(r); + return *this; + } + + template + iterator_range& operator=(const SinglePassRange& r) + { + this->assign(r); + return *this; + } + + iterator_range& advance_begin( + BOOST_DEDUCED_TYPENAME base_type::difference_type n) + { + std::advance(this->m_Begin, n); + return *this; + } + + iterator_range& advance_end( + BOOST_DEDUCED_TYPENAME base_type::difference_type n) + { + std::advance(this->m_End, n); + return *this; + } + + protected: + // + // Allow subclasses an easy way to access the + // base type + // + typedef iterator_range iterator_range_; + }; + +// iterator range free-standing operators ---------------------------// + + ///////////////////////////////////////////////////////////////////// + // comparison operators + ///////////////////////////////////////////////////////////////////// + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator==( const ForwardRange& l, const iterator_range& r ) + { + return boost::equal( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator!=( const ForwardRange& l, const iterator_range& r ) + { + return !boost::equal( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator<( const ForwardRange& l, const iterator_range& r ) + { + return iterator_range_detail::less_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator<=( const ForwardRange& l, const iterator_range& r ) + { + return iterator_range_detail::less_or_equal_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator>( const ForwardRange& l, const iterator_range& r ) + { + return iterator_range_detail::greater_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator>=( const ForwardRange& l, const iterator_range& r ) + { + return iterator_range_detail::greater_or_equal_than( l, r ); + } + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +#else + template< class Iterator1T, class Iterator2T > + inline bool + operator==( const iterator_range& l, const iterator_range& r ) + { + return boost::equal( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator==( const iterator_range& l, const ForwardRange& r ) + { + return boost::equal( l, r ); + } + + + template< class Iterator1T, class Iterator2T > + inline bool + operator!=( const iterator_range& l, const iterator_range& r ) + { + return !boost::equal( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator!=( const iterator_range& l, const ForwardRange& r ) + { + return !boost::equal( l, r ); + } + + + template< class Iterator1T, class Iterator2T > + inline bool + operator<( const iterator_range& l, const iterator_range& r ) + { + return iterator_range_detail::less_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator<( const iterator_range& l, const ForwardRange& r ) + { + return iterator_range_detail::less_than( l, r ); + } + + template< class Iterator1T, class Iterator2T > + inline bool + operator<=( const iterator_range& l, const iterator_range& r ) + { + return iterator_range_detail::less_or_equal_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator<=( const iterator_range& l, const ForwardRange& r ) + { + return iterator_range_detail::less_or_equal_than( l, r ); + } + + template< class Iterator1T, class Iterator2T > + inline bool + operator>( const iterator_range& l, const iterator_range& r ) + { + return iterator_range_detail::greater_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator>( const iterator_range& l, const ForwardRange& r ) + { + return iterator_range_detail::greater_than( l, r ); + } + + template< class Iterator1T, class Iterator2T > + inline bool + operator>=( const iterator_range& l, const iterator_range& r ) + { + return iterator_range_detail::greater_or_equal_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + operator>=( const iterator_range& l, const ForwardRange& r ) + { + return iterator_range_detail::greater_or_equal_than( l, r ); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +// iterator range utilities -----------------------------------------// + + //! iterator_range construct helper + /*! + Construct an \c iterator_range from a pair of iterators + + \param Begin A begin iterator + \param End An end iterator + \return iterator_range object + */ + template< typename IteratorT > + inline iterator_range< IteratorT > + make_iterator_range( IteratorT Begin, IteratorT End ) + { + return iterator_range( Begin, End ); + } + + template + inline iterator_range + make_iterator_range_n(IteratorT first, IntegerT n) + { + return iterator_range(first, boost::next(first, n)); + } + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( Range& r ) + { + return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + ( boost::begin( r ), boost::end( r ) ); + } + +#else + //! iterator_range construct helper + /*! + Construct an \c iterator_range from a \c Range containing the begin + and end iterators. + */ + template< class ForwardRange > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( ForwardRange& r ) + { + return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + ( r, iterator_range_detail::range_tag() ); + } + + template< class ForwardRange > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( const ForwardRange& r ) + { + return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + ( r, iterator_range_detail::const_range_tag() ); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + namespace iterator_range_detail + { + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_range_impl( Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + // + // Not worth the effort + // + //if( advance_begin == 0 && advance_end == 0 ) + // return make_iterator_range( r ); + // + + BOOST_DEDUCED_TYPENAME range_iterator::type + new_begin = boost::begin( r ), + new_end = boost::end( r ); + std::advance( new_begin, advance_begin ); + std::advance( new_end, advance_end ); + return make_iterator_range( new_begin, new_end ); + } + } + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + return iterator_range_detail::make_range_impl( r, advance_begin, advance_end ); + } + +#else + + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + return iterator_range_detail::make_range_impl( r, advance_begin, advance_end ); + } + + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( const Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + return iterator_range_detail::make_range_impl( r, advance_begin, advance_end ); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! copy a range into a sequence + /*! + Construct a new sequence of the specified type from the elements + in the given range + + \param Range An input range + \return New sequence + */ + template< typename SeqT, typename Range > + inline SeqT copy_range( const Range& r ) + { + return SeqT( boost::begin( r ), boost::end( r ) ); + } + +} // namespace 'boost' + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) + #pragma warning( pop ) +#endif + +#endif + diff --git a/boost/range/iterator_range_hash.hpp b/boost/range/iterator_range_hash.hpp new file mode 100644 index 0000000..615d22f --- /dev/null +++ b/boost/range/iterator_range_hash.hpp @@ -0,0 +1,22 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014 +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#include +#include + +namespace boost +{ + +template +std::size_t hash_value(const iterator_range& rng) +{ + return boost::hash_range(rng.begin(), rng.end()); +} + +} // namespace boost diff --git a/boost/range/iterator_range_io.hpp b/boost/range/iterator_range_io.hpp new file mode 100644 index 0000000..8c29400 --- /dev/null +++ b/boost/range/iterator_range_io.hpp @@ -0,0 +1,93 @@ +// 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_ITERATOR_RANGE_IO_HPP_INCLUDED +#define BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED + +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) + #pragma warning( push ) + #pragma warning( disable : 4996 ) +#endif + +// From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for Cray X1 patch. +#ifndef BOOST_OLD_IOSTREAMS +# if defined(__STL_CONFIG_H) && \ + !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \ + /**/ +# define BOOST_OLD_IOSTREAMS +# endif +#endif // #ifndef BOOST_OLD_IOSTREAMS + +#ifndef _STLP_NO_IOSTREAMS +# ifndef BOOST_OLD_IOSTREAMS +# include +# else +# include +# endif +#endif // _STLP_NO_IOSTREAMS + +#include +#include +#include +#include + +namespace boost +{ + +#ifndef _STLP_NO_IOSTREAMS +# ifndef BOOST_OLD_IOSTREAMS + + //! iterator_range output operator + /*! + Output the range to an ostream. Elements are outputted + in a sequence without separators. + */ + template< typename IteratorT, typename Elem, typename Traits > + inline std::basic_ostream& operator<<( + std::basic_ostream& Os, + const iterator_range& r ) + { + std::copy( r.begin(), r.end(), + std::ostream_iterator< BOOST_DEDUCED_TYPENAME + iterator_value::type, + Elem, Traits>(Os) ); + return Os; + } + +# else + + //! iterator_range output operator + /*! + Output the range to an ostream. Elements are outputted + in a sequence without separators. + */ + template< typename IteratorT > + inline std::ostream& operator<<( + std::ostream& Os, + const iterator_range& r ) + { + std::copy( r.begin(), r.end(), std::ostream_iterator(Os)); + return Os; + } + +# endif +#endif // _STLP_NO_IOSTREAMS + +} // namespace boost + +#undef BOOST_OLD_IOSTREAMS + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) + #pragma warning(pop) +#endif + +#endif // include guard diff --git a/boost/range/join.hpp b/boost/range/join.hpp new file mode 100644 index 0000000..aacc0a3 --- /dev/null +++ b/boost/range/join.hpp @@ -0,0 +1,91 @@ +// 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_JOIN_HPP_INCLUDED +#define BOOST_RANGE_JOIN_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class joined_type +{ +public: + typedef iterator_range< + range_detail::join_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_value::type + > + > type; +}; + + } // namespace range_detail + +namespace range +{ + +template +class joined_range + : public range_detail::joined_type::type +{ + typedef range_detail::join_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_value::type + > iterator_t; + + typedef BOOST_DEDUCED_TYPENAME range_detail::joined_type< + SinglePassRange1, SinglePassRange2>::type base_t; +public: + joined_range(SinglePassRange1& rng1, SinglePassRange2& rng2) + : base_t( + iterator_t(rng1, rng2, range_detail::join_iterator_begin_tag()), + iterator_t(rng1, rng2, range_detail::join_iterator_end_tag()) + ) + { + } +}; + +template +joined_range +join(const SinglePassRange1& r1, const SinglePassRange2& r2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + return joined_range(r1, r2); +} + +template +joined_range +join(SinglePassRange1& r1, SinglePassRange2& r2) +{ + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + + return joined_range(r1, r2); +} + +} // namespace range + +using ::boost::range::joined_range; +using ::boost::range::join; + +} // namespace boost + +#endif // include guard diff --git a/boost/range/metafunctions.hpp b/boost/range/metafunctions.hpp new file mode 100644 index 0000000..9dc59d0 --- /dev/null +++ b/boost/range/metafunctions.hpp @@ -0,0 +1,31 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_METAFUNCTIONS_HPP +#define BOOST_RANGE_METAFUNCTIONS_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/boost/range/mfc.hpp b/boost/range/mfc.hpp new file mode 100644 index 0000000..058e54e --- /dev/null +++ b/boost/range/mfc.hpp @@ -0,0 +1,984 @@ +#ifndef BOOST_RANGE_MFC_HPP +#define BOOST_RANGE_MFC_HPP + + + + +// Boost.Range MFC Extension +// +// Copyright Shunsuke Sogame 2005-2006. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + + +// config +// + + +#include // _MFC_VER + + +#if !defined(BOOST_RANGE_MFC_NO_CPAIR) + #if (_MFC_VER < 0x0700) // dubious + #define BOOST_RANGE_MFC_NO_CPAIR + #endif +#endif + + +#if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) + #if (_MFC_VER < 0x0700) // dubious + #define BOOST_RANGE_MFC_HAS_LEGACY_STRING + #endif +#endif + + +// A const collection of old MFC doesn't return const reference. +// +#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + #if (_MFC_VER < 0x0700) // dubious + #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF + #endif +#endif + + + + +// forward declarations +// + + +template< class Type, class ArgType > +class CArray; + +template< class Type, class ArgType > +class CList; + +template< class Key, class ArgKey, class Mapped, class ArgMapped > +class CMap; + +template< class BaseClass, class PtrType > +class CTypedPtrArray; + +template< class BaseClass, class PtrType > +class CTypedPtrList; + +template< class BaseClass, class KeyPtrType, class MappedPtrType > +class CTypedPtrMap; + + + + +// extended customizations +// + + +#include // ptrdiff_t +#include // pair +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // legacy CString +#include // CXXXArray, CXXXList, CMapXXXToXXX +#include + + +namespace boost { namespace range_detail_microsoft { + + + // mfc_ptr_array_iterator + // + // 'void **' is not convertible to 'void const **', + // so we define... + // + + template< class ArrayT, class PtrType > + struct mfc_ptr_array_iterator; + + template< class ArrayT, class PtrType > + struct mfc_ptr_array_iterator_super + { + typedef iterator_adaptor< + mfc_ptr_array_iterator, + std::ptrdiff_t, // Base! + PtrType, // Value + random_access_traversal_tag, + use_default, + std::ptrdiff_t // Difference + > type; + }; + + template< class ArrayT, class PtrType > + struct mfc_ptr_array_iterator : + mfc_ptr_array_iterator_super::type + { + private: + typedef mfc_ptr_array_iterator self_t; + typedef typename mfc_ptr_array_iterator_super::type super_t; + typedef typename super_t::reference ref_t; + + public: + explicit mfc_ptr_array_iterator() + { } + + explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) : + super_t(index), m_parr(boost::addressof(arr)) + { } + + template< class, class > friend struct mfc_ptr_array_iterator; + template< class ArrayT_, class PtrType_ > + mfc_ptr_array_iterator(mfc_ptr_array_iterator const& other) : + super_t(other.base()), m_parr(other.m_parr) + { } + + private: + ArrayT *m_parr; + + friend class iterator_core_access; + ref_t dereference() const + { + BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range"); + return *( m_parr->GetData() + this->base() ); + } + + bool equal(self_t const& other) const + { + BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible"); + return this->base() == other.base(); + } + }; + + struct mfc_ptr_array_functions + { + template< class Iterator, class X > + Iterator begin(X& x) + { + return Iterator(x, 0); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return Iterator(x, x.GetSize()); + } + }; + + + // arrays + // + + template< > + struct customization< ::CByteArray > : + array_functions + { + template< class X > + struct meta + { + typedef BYTE val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< > + struct customization< ::CDWordArray > : + array_functions + { + template< class X > + struct meta + { + typedef DWORD val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< > + struct customization< ::CObArray > : + mfc_ptr_array_functions + { + template< class X > + struct meta + { + typedef mfc_ptr_array_iterator mutable_iterator; + typedef mfc_ptr_array_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CPtrArray > : + mfc_ptr_array_functions + { + template< class X > + struct meta + { + typedef mfc_ptr_array_iterator mutable_iterator; + typedef mfc_ptr_array_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CStringArray > : + array_functions + { + template< class X > + struct meta + { + typedef ::CString val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< > + struct customization< ::CUIntArray > : + array_functions + { + template< class X > + struct meta + { + typedef UINT val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< > + struct customization< ::CWordArray > : + array_functions + { + template< class X > + struct meta + { + typedef WORD val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + // lists + // + + template< > + struct customization< ::CObList > : + list_functions + { + template< class X > + struct meta + { + typedef list_iterator mutable_iterator; + #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + typedef list_iterator const_iterator; + #else + typedef list_iterator const_iterator; + #endif + }; + }; + + + template< > + struct customization< ::CPtrList > : + list_functions + { + template< class X > + struct meta + { + typedef list_iterator mutable_iterator; + #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + typedef list_iterator const_iterator; + #else + typedef list_iterator const_iterator; + #endif + }; + }; + + + template< > + struct customization< ::CStringList > : + list_functions + { + template< class X > + struct meta + { + typedef ::CString val_t; + + typedef list_iterator mutable_iterator; + #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + typedef list_iterator const_iterator; + #else + typedef list_iterator const_iterator; + #endif + }; + }; + + + // mfc_map_iterator + // + + template< class MapT, class KeyT, class MappedT > + struct mfc_map_iterator; + + template< class MapT, class KeyT, class MappedT > + struct mfc_map_iterator_super + { + typedef iterator_facade< + mfc_map_iterator, + std::pair, + forward_traversal_tag, + std::pair const + > type; + }; + + template< class MapT, class KeyT, class MappedT > + struct mfc_map_iterator : + mfc_map_iterator_super::type + { + private: + typedef mfc_map_iterator self_t; + typedef typename mfc_map_iterator_super::type super_t; + typedef typename super_t::reference ref_t; + + public: + explicit mfc_map_iterator() + { } + + explicit mfc_map_iterator(MapT const& map, POSITION pos) : + m_pmap(boost::addressof(map)), m_posNext(pos) + { + increment(); + } + + explicit mfc_map_iterator(MapT const& map) : + m_pmap(&map), m_pos(0) // end iterator + { } + + template< class, class, class > friend struct mfc_map_iterator; + template< class MapT_, class KeyT_, class MappedT_> + mfc_map_iterator(mfc_map_iterator const& other) : + m_pmap(other.m_pmap), + m_pos(other.m_pos), m_posNext(other.m_posNext), + m_key(other.m_key), m_mapped(other.m_mapped) + { } + + private: + MapT const *m_pmap; + POSITION m_pos, m_posNext; + KeyT m_key; MappedT m_mapped; + + friend class iterator_core_access; + ref_t dereference() const + { + BOOST_ASSERT(m_pos != 0 && "out of range"); + return std::make_pair(m_key, m_mapped); + } + + void increment() + { + BOOST_ASSERT(m_pos != 0 && "out of range"); + + if (m_posNext == 0) { + m_pos = 0; + return; + } + + m_pos = m_posNext; + m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped); + } + + bool equal(self_t const& other) const + { + BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible"); + return m_pos == other.m_pos; + } + }; + + struct mfc_map_functions + { + template< class Iterator, class X > + Iterator begin(X& x) + { + return Iterator(x, x.GetStartPosition()); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return Iterator(x); + } + }; + + +#if !defined(BOOST_RANGE_MFC_NO_CPAIR) + + + // mfc_cpair_map_iterator + // + // used by ::CMap and ::CMapStringToString + // + + template< class MapT, class PairT > + struct mfc_cpair_map_iterator; + + template< class MapT, class PairT > + struct mfc_pget_map_iterator_super + { + typedef iterator_facade< + mfc_cpair_map_iterator, + PairT, + forward_traversal_tag + > type; + }; + + template< class MapT, class PairT > + struct mfc_cpair_map_iterator : + mfc_pget_map_iterator_super::type + { + private: + typedef mfc_cpair_map_iterator self_t; + typedef typename mfc_pget_map_iterator_super::type super_t; + typedef typename super_t::reference ref_t; + + public: + explicit mfc_cpair_map_iterator() + { } + + explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) : + m_pmap(boost::addressof(map)), m_pp(pp) + { } + + template< class, class > friend struct mfc_cpair_map_iterator; + template< class MapT_, class PairT_> + mfc_cpair_map_iterator(mfc_cpair_map_iterator const& other) : + m_pmap(other.m_pmap), m_pp(other.m_pp) + { } + + private: + MapT *m_pmap; + PairT *m_pp; + + friend class iterator_core_access; + ref_t dereference() const + { + BOOST_ASSERT(m_pp != 0 && "out of range"); + return *m_pp; + } + + void increment() + { + BOOST_ASSERT(m_pp != 0 && "out of range"); + m_pp = m_pmap->PGetNextAssoc(m_pp); + } + + bool equal(self_t const& other) const + { + BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible"); + return m_pp == other.m_pp; + } + }; + + struct mfc_cpair_map_functions + { + template< class Iterator, class X > + Iterator begin(X& x) + { + // Workaround: + // Assertion fails if empty. + // MFC document is wrong. + #if !defined(NDEBUG) + if (x.GetCount() == 0) + return Iterator(x, 0); + #endif + + return Iterator(x, x.PGetFirstAssoc()); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return Iterator(x, 0); + } + }; + + +#endif // !defined(BOOST_RANGE_MFC_NO_CPAIR) + + + // maps + // + + template< > + struct customization< ::CMapPtrToWord > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef void *key_t; + typedef WORD mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CMapPtrToPtr > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef void *key_t; + typedef void *mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CMapStringToOb > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef ::CString key_t; + typedef ::CObject *mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CMapStringToPtr > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef ::CString key_t; + typedef void *mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CMapStringToString > : + #if !defined(BOOST_RANGE_MFC_NO_CPAIR) + mfc_cpair_map_functions + #else + mfc_map_functions + #endif + { + template< class X > + struct meta + { + #if !defined(BOOST_RANGE_MFC_NO_CPAIR) + typedef typename X::CPair pair_t; + + typedef mfc_cpair_map_iterator mutable_iterator; + typedef mfc_cpair_map_iterator const_iterator; + #else + typedef ::CString key_t; + typedef ::CString mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + #endif + }; + }; + + + template< > + struct customization< ::CMapWordToOb > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef WORD key_t; + typedef ::CObject *mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + template< > + struct customization< ::CMapWordToPtr > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef WORD key_t; + typedef void *mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + // templates + // + + template< class Type, class ArgType > + struct customization< ::CArray > : + array_functions + { + template< class X > + struct meta + { + typedef Type val_t; + + typedef val_t *mutable_iterator; + typedef val_t const *const_iterator; + }; + }; + + + template< class Type, class ArgType > + struct customization< ::CList > : + list_functions + { + template< class X > + struct meta + { + typedef Type val_t; + + typedef list_iterator mutable_iterator; + #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + typedef list_iterator const_iterator; + #else + typedef list_iterator const_iterator; + #endif + }; + }; + + + template< class Key, class ArgKey, class Mapped, class ArgMapped > + struct customization< ::CMap > : + #if !defined(BOOST_RANGE_MFC_NO_CPAIR) + mfc_cpair_map_functions + #else + mfc_map_functions + #endif + { + template< class X > + struct meta + { + #if !defined(BOOST_RANGE_MFC_NO_CPAIR) + typedef typename X::CPair pair_t; + + typedef mfc_cpair_map_iterator mutable_iterator; + typedef mfc_cpair_map_iterator const_iterator; + #else + typedef Key key_t; + typedef Mapped mapped_t; + + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + #endif + }; + }; + + + template< class BaseClass, class PtrType > + struct customization< ::CTypedPtrArray > + { + template< class X > + struct fun + { + typedef typename remove_pointer::type val_t; + + typedef typename mpl::if_< is_const, + val_t const, + val_t + >::type val_t_; + + typedef val_t_ * const result_type; + + template< class PtrType_ > + result_type operator()(PtrType_ p) const + { + return static_cast(p); + } + }; + + template< class X > + struct meta + { + typedef typename compatible_mutable_iterator::type miter_t; + typedef typename range_const_iterator::type citer_t; + + typedef transform_iterator, miter_t> mutable_iterator; + typedef transform_iterator, citer_t> const_iterator; + }; + + template< class Iterator, class X > + Iterator begin(X& x) + { + return Iterator(boost::begin(x), fun()); + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return Iterator(boost::end(x), fun()); + } + }; + + + template< class BaseClass, class PtrType > + struct customization< ::CTypedPtrList > : + list_functions + { + template< class X > + struct meta + { + typedef typename remove_pointer::type val_t; + + // not l-value + typedef list_iterator mutable_iterator; + typedef list_iterator const_iterator; + }; + }; + + + template< class BaseClass, class KeyPtrType, class MappedPtrType > + struct customization< ::CTypedPtrMap > : + mfc_map_functions + { + template< class X > + struct meta + { + typedef mfc_map_iterator mutable_iterator; + typedef mutable_iterator const_iterator; + }; + }; + + + // strings + // + +#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) + + template< > + struct customization< ::CString > + { + template< class X > + struct meta + { + // LPTSTR/LPCTSTR is not always defined in . + typedef TCHAR *mutable_iterator; + typedef TCHAR const *const_iterator; + }; + + template< class Iterator, class X > + typename mutable_::type begin(X& x) + { + return x.GetBuffer(0); + } + + template< class Iterator, class X > + Iterator begin(X const& x) + { + return x; + } + + template< class Iterator, class X > + Iterator end(X& x) + { + return begin(x) + x.GetLength(); + } + }; + +#endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) + + +} } // namespace boost::range_detail_microsoft + + + + +// range customizations +// + + +// arrays +// +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CByteArray +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CDWordArray +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CStringArray +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CUIntArray +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CWordArray +) + + +// lists +// +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CObList +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CPtrList +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CStringList +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CObArray +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CPtrArray +) + + +// maps +// +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapPtrToWord +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapPtrToPtr +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapStringToOb +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapStringToPtr +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapStringToString +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapWordToOb +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMapWordToPtr +) + + +// templates +// +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CArray, 2 +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CList, 2 +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CMap, 4 +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CTypedPtrArray, 2 +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CTypedPtrList, 2 +) + +BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CTypedPtrMap, 3 +) + + +// strings +// +#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) + + BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( + boost::range_detail_microsoft::using_type_as_tag, + BOOST_PP_NIL, CString + ) + +#endif + + + + +#endif diff --git a/boost/range/mfc_map.hpp b/boost/range/mfc_map.hpp new file mode 100644 index 0000000..2cd42b4 --- /dev/null +++ b/boost/range/mfc_map.hpp @@ -0,0 +1,114 @@ +// Boost.Range library +// +// Copyright Adam D. Walling 2012. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_ADAPTOR_MFC_MAP_HPP +#define BOOST_RANGE_ADAPTOR_MFC_MAP_HPP + +#if !defined(BOOST_RANGE_MFC_NO_CPAIR) + +#include +#include + +namespace boost +{ + namespace range_detail + { + // CMap and CMapStringToString range iterators return CPair, + // which has a key and value member. Other MFC range iterators + // already return adapted std::pair objects. This allows usage + // of the map_keys and map_values range adaptors with CMap + // and CMapStringToString + + // CPair has a VALUE value member, and a KEY key member; we will + // use VALUE& as the result_type consistent with CMap::operator[] + + // specialization for CMap + template + struct select_first< CMap > + { + typedef BOOST_DEDUCED_TYPENAME CMap map_type; + typedef BOOST_DEDUCED_TYPENAME range_reference::type argument_type; + typedef BOOST_DEDUCED_TYPENAME const KEY& result_type; + + result_type operator()( argument_type r ) const + { + return r.key; + } + }; + + template + struct select_second_mutable< CMap > + { + typedef BOOST_DEDUCED_TYPENAME CMap map_type; + typedef BOOST_DEDUCED_TYPENAME range_reference::type argument_type; + typedef BOOST_DEDUCED_TYPENAME VALUE& result_type; + + result_type operator()( argument_type r ) const + { + return r.value; + } + }; + + template + struct select_second_const< CMap > + { + typedef BOOST_DEDUCED_TYPENAME CMap map_type; + typedef BOOST_DEDUCED_TYPENAME range_reference::type argument_type; + typedef BOOST_DEDUCED_TYPENAME const VALUE& result_type; + + result_type operator()( argument_type r ) const + { + return r.value; + } + }; + + + // specialization for CMapStringToString + template<> + struct select_first< CMapStringToString > + { + typedef range_reference::type argument_type; + typedef const CString& result_type; + + result_type operator()( argument_type r ) const + { + return r.key; + } + }; + + template<> + struct select_second_mutable< CMapStringToString > + { + typedef range_reference::type argument_type; + typedef CString& result_type; + + result_type operator()( argument_type r ) const + { + return r.value; + } + }; + + template<> + struct select_second_const< CMapStringToString > + { + typedef range_reference::type argument_type; + typedef const CString& result_type; + + result_type operator()( argument_type r ) const + { + return r.value; + } + }; + } // 'range_detail' +} // 'boost' + +#endif // !defined(BOOST_RANGE_MFC_NO_CPAIR) + +#endif diff --git a/boost/range/mutable_iterator.hpp b/boost/range/mutable_iterator.hpp new file mode 100644 index 0000000..b924666 --- /dev/null +++ b/boost/range/mutable_iterator.hpp @@ -0,0 +1,79 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_MUTABLE_ITERATOR_HPP +#define BOOST_RANGE_MUTABLE_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + + ////////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////////// + + namespace range_detail + { + +BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator ) + +template< typename C > +struct range_mutable_iterator + : range_detail::extract_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type> +{}; + +////////////////////////////////////////////////////////////////////////// +// pair +////////////////////////////////////////////////////////////////////////// + +template< typename Iterator > +struct range_mutable_iterator< std::pair > +{ + typedef Iterator type; +}; + +////////////////////////////////////////////////////////////////////////// +// array +////////////////////////////////////////////////////////////////////////// + +template< typename T, std::size_t sz > +struct range_mutable_iterator< T[sz] > +{ + typedef T* type; +}; + + } // namespace range_detail + +template +struct range_mutable_iterator + : range_detail::range_mutable_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type + > +{ +}; + +} // namespace boost + +#include + +#endif diff --git a/boost/range/numeric.hpp b/boost/range/numeric.hpp new file mode 100644 index 0000000..d1510cd --- /dev/null +++ b/boost/range/numeric.hpp @@ -0,0 +1,188 @@ +// Copyright 2009-2014 Neil Groves. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Copyright 2006 Thorsten Ottosen. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Copyright 2004 Eric Niebler. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Contains range-based versions of the numeric std algorithms +// +#if defined(_MSC_VER) + #pragma once +#endif + +#ifndef BOOST_RANGE_NUMERIC_HPP +#define BOOST_RANGE_NUMERIC_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost +{ + template + inline Value accumulate(const SinglePassRange& rng, Value init) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return std::accumulate(boost::begin(rng), boost::end(rng), init); + } + + template + inline Value accumulate(const SinglePassRange& rng, Value init, + BinaryOperation op) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept )); + + return std::accumulate(boost::begin(rng), boost::end(rng), init, op); + } + + namespace range_detail + { + template + inline bool inner_product_precondition( + const SinglePassRange1&, + const SinglePassRange2&, + std::input_iterator_tag, + std::input_iterator_tag) + { + return true; + } + + template + inline bool inner_product_precondition( + const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + std::forward_iterator_tag, + std::forward_iterator_tag) + { + return boost::size(rng2) >= boost::size(rng1); + } + + } // namespace range_detail + + template< + class SinglePassRange1, + class SinglePassRange2, + class Value + > + inline Value inner_product( + const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + Value init) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + BOOST_ASSERT( + range_detail::inner_product_precondition( + rng1, rng2, + typename range_category::type(), + typename range_category::type())); + + return std::inner_product( + boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), init); + } + + template< + class SinglePassRange1, + class SinglePassRange2, + class Value, + class BinaryOperation1, + class BinaryOperation2 + > + inline Value inner_product( + const SinglePassRange1& rng1, + const SinglePassRange2& rng2, + Value init, + BinaryOperation1 op1, + BinaryOperation2 op2) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + BOOST_ASSERT( + range_detail::inner_product_precondition( + rng1, rng2, + typename range_category::type(), + typename range_category::type())); + + return std::inner_product( + boost::begin(rng1), boost::end(rng1), + boost::begin(rng2), init, op1, op2); + } + + template + inline OutputIterator partial_sum(const SinglePassRange& rng, + OutputIterator result) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return std::partial_sum(boost::begin(rng), boost::end(rng), result); + } + + template + inline OutputIterator partial_sum( + const SinglePassRange& rng, + OutputIterator result, + BinaryOperation op) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return std::partial_sum(boost::begin(rng), boost::end(rng), result, op); + } + + template + inline OutputIterator adjacent_difference( + const SinglePassRange& rng, + OutputIterator result) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return std::adjacent_difference(boost::begin(rng), boost::end(rng), + result); + } + + template + inline OutputIterator adjacent_difference( + const SinglePassRange& rng, + OutputIterator result, + BinaryOperation op) + { + BOOST_RANGE_CONCEPT_ASSERT(( + SinglePassRangeConcept)); + + return std::adjacent_difference(boost::begin(rng), boost::end(rng), + result, op); + } + +} // namespace boost + +#endif diff --git a/boost/range/pointer.hpp b/boost/range/pointer.hpp new file mode 100644 index 0000000..b1e8dc5 --- /dev/null +++ b/boost/range/pointer.hpp @@ -0,0 +1,30 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_POINTER_TYPE_HPP +#define BOOST_RANGE_POINTER_TYPE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + template< class T > + struct range_pointer + : iterator_pointer< BOOST_DEDUCED_TYPENAME range_iterator::type > + { }; +} + +#endif diff --git a/boost/range/range_fwd.hpp b/boost/range/range_fwd.hpp new file mode 100644 index 0000000..0e6e00f --- /dev/null +++ b/boost/range/range_fwd.hpp @@ -0,0 +1,63 @@ +// Boost.Range library +// +// Copyright Neil Groves 2003-2004. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_RANGE_FWD_HPP_INCLUDED +#define BOOST_RANGE_RANGE_FWD_HPP_INCLUDED + +namespace boost +{ + +// Extension points + template + struct range_iterator; + + template + struct range_mutable_iterator; + + template + struct range_const_iterator; + +// Core classes + template + class iterator_range; + + template + class sub_range; + +// Meta-functions + template + struct range_category; + + template + struct range_difference; + + template + struct range_pointer; + + template + struct range_reference; + + template + struct range_reverse_iterator; + + template + struct range_size; + + template + struct range_value; + + template + struct has_range_iterator; + + template + struct has_range_const_iterator; + +} // namespace boost + +#endif // include guard diff --git a/boost/range/rbegin.hpp b/boost/range/rbegin.hpp new file mode 100644 index 0000000..6d66de9 --- /dev/null +++ b/boost/range/rbegin.hpp @@ -0,0 +1,65 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_RBEGIN_HPP +#define BOOST_RANGE_RBEGIN_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost +{ + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template< class C > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +rbegin( C& c ) +{ + return BOOST_DEDUCED_TYPENAME range_reverse_iterator::type( boost::end( c ) ); +} + +#else + +template< class C > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +rbegin( C& c ) +{ + typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator::type + iter_type; + return iter_type( boost::end( c ) ); +} + +template< class C > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +rbegin( const C& c ) +{ + typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator::type + iter_type; + return iter_type( boost::end( c ) ); +} + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template< class T > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +const_rbegin( const T& r ) +{ + return boost::rbegin( r ); +} + +} // namespace 'boost' + +#endif + diff --git a/boost/range/reference.hpp b/boost/range/reference.hpp new file mode 100644 index 0000000..c664c38 --- /dev/null +++ b/boost/range/reference.hpp @@ -0,0 +1,29 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_REFERENCE_TYPE_HPP +#define BOOST_RANGE_REFERENCE_TYPE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + template< class T > + struct range_reference : iterator_reference< typename range_iterator::type > + { }; +} + +#endif diff --git a/boost/range/rend.hpp b/boost/range/rend.hpp new file mode 100644 index 0000000..ef70407 --- /dev/null +++ b/boost/range/rend.hpp @@ -0,0 +1,65 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_REND_HPP +#define BOOST_RANGE_REND_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost +{ + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template< class C > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +rend( C& c ) +{ + return BOOST_DEDUCED_TYPENAME range_reverse_iterator::type( boost::begin( c ) ); +} + +#else + +template< class C > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +rend( C& c ) +{ + typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator::type + iter_type; + return iter_type( boost::begin( c ) ); +} + +template< class C > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +rend( const C& c ) +{ + typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator::type + iter_type; + return iter_type( boost::begin( c ) ); +} + +#endif + +template< class T > +inline BOOST_DEDUCED_TYPENAME range_reverse_iterator::type +const_rend( const T& r ) +{ + return boost::rend( r ); +} + +} // namespace 'boost' + +#endif + diff --git a/boost/range/result_iterator.hpp b/boost/range/result_iterator.hpp new file mode 100644 index 0000000..54e343d --- /dev/null +++ b/boost/range/result_iterator.hpp @@ -0,0 +1,33 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_RESULT_ITERATOR_HPP +#define BOOST_RANGE_RESULT_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +namespace boost +{ + // + // This interface is deprecated, use range_iterator + // + + template< typename C > + struct range_result_iterator : range_iterator + { }; + +} // namespace boost + + +#endif diff --git a/boost/range/reverse_iterator.hpp b/boost/range/reverse_iterator.hpp new file mode 100644 index 0000000..0aa0130 --- /dev/null +++ b/boost/range/reverse_iterator.hpp @@ -0,0 +1,42 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_REVERSE_ITERATOR_HPP +#define BOOST_RANGE_REVERSE_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + + +namespace boost +{ + ////////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////////// + + template< typename T > + struct range_reverse_iterator + { + typedef reverse_iterator< + BOOST_DEDUCED_TYPENAME range_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type>::type > type; + }; + + +} // namespace boost + + +#endif diff --git a/boost/range/reverse_result_iterator.hpp b/boost/range/reverse_result_iterator.hpp new file mode 100644 index 0000000..d375cfd --- /dev/null +++ b/boost/range/reverse_result_iterator.hpp @@ -0,0 +1,32 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP +#define BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +namespace boost +{ + // + // This interface is deprecated, use range_reverse_iterator + // + + template< typename C > + struct range_reverse_result_iterator : range_reverse_iterator + { }; + +} // namespace boost + +#endif diff --git a/boost/range/size.hpp b/boost/range/size.hpp new file mode 100644 index 0000000..d007bfc --- /dev/null +++ b/boost/range/size.hpp @@ -0,0 +1,67 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_SIZE_HPP +#define BOOST_RANGE_SIZE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + + template + inline typename ::boost::enable_if< + has_member_size, + typename range_size::type + >::type + range_calculate_size(const SinglePassRange& rng) + { + return rng.size(); + } + + template + inline typename disable_if< + has_member_size, + typename range_size::type + >::type + range_calculate_size(const SinglePassRange& rng) + { + return std::distance(boost::begin(rng), boost::end(rng)); + } + } + + template + inline typename range_size::type + size(const SinglePassRange& rng) + { +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(__GNUC__, < 3) \ + /**/ + using namespace range_detail; +#endif + return range_calculate_size(rng); + } + +} // namespace 'boost' + +#endif diff --git a/boost/range/size_type.hpp b/boost/range/size_type.hpp new file mode 100644 index 0000000..db5a59b --- /dev/null +++ b/boost/range/size_type.hpp @@ -0,0 +1,98 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_SIZE_TYPE_HPP +#define BOOST_RANGE_SIZE_TYPE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace detail + { + + ////////////////////////////////////////////////////////////////////////// + // default + ////////////////////////////////////////////////////////////////////////// + + template + class has_size_type + { + typedef char no_type; + struct yes_type { char dummy[2]; }; + + template + static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x); + + template + static no_type test(...); + + public: + static const bool value = sizeof(test(0)) == sizeof(yes_type); + }; + + template + struct range_size + { + typedef BOOST_DEDUCED_TYPENAME make_unsigned< + BOOST_DEDUCED_TYPENAME range_difference::type + >::type type; + }; + + template + struct range_size< + C, + BOOST_DEDUCED_TYPENAME ::boost::enable_if, void>::type + > + { + typedef BOOST_DEDUCED_TYPENAME C::size_type type; + }; + + } + + template< class T > + struct range_size : + detail::range_size + { +// Very strange things happen on some compilers that have the range concept +// asserts disabled. This preprocessor condition is clearly redundant on a +// working compiler but is vital for at least some compilers such as clang 4.2 +// but only on the Mac! +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1 + BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept)); +#endif + }; + + template< class T > + struct range_size + : detail::range_size + { +#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1 + BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept)); +#endif + }; + +} // namespace boost + + + +#endif diff --git a/boost/range/sub_range.hpp b/boost/range/sub_range.hpp new file mode 100644 index 0000000..8d5d168 --- /dev/null +++ b/boost/range/sub_range.hpp @@ -0,0 +1,287 @@ +// Boost.Range library +// +// Copyright Neil Groves 2009. +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_SUB_RANGE_HPP +#define BOOST_RANGE_SUB_RANGE_HPP + +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) + #pragma warning( push ) + #pragma warning( disable : 4996 ) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class sub_range_base + : public iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type + > +{ + typedef iterator_range< + BOOST_DEDUCED_TYPENAME range_iterator::type + > base; + +protected: + typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_; + +public: + typedef BOOST_DEDUCED_TYPENAME range_value::type value_type; + typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator; + typedef BOOST_DEDUCED_TYPENAME range_iterator::type const_iterator; + typedef BOOST_DEDUCED_TYPENAME range_difference::type difference_type; + typedef BOOST_DEDUCED_TYPENAME range_size::type size_type; + typedef BOOST_DEDUCED_TYPENAME range_reference::type reference; + typedef BOOST_DEDUCED_TYPENAME range_reference::type const_reference; + + sub_range_base() + { + } + + template + sub_range_base(Iterator first, Iterator last) + : base(first, last) + { + } + + reference front() + { + return base::front(); + } + + const_reference front() const + { + return base::front(); + } +}; + +template +class sub_range_base + : public sub_range_base +{ + typedef sub_range_base base; +public: + sub_range_base() + { + } + + template + sub_range_base(Iterator first, Iterator last) + : base(first, last) + { + } + + BOOST_DEDUCED_TYPENAME base::reference back() + { + return base::back(); + } + + BOOST_DEDUCED_TYPENAME base::const_reference back() const + { + return base::back(); + } +}; + +template +class sub_range_base + : public sub_range_base +{ + typedef sub_range_base base; + +public: + sub_range_base() + { + } + + template + sub_range_base(Iterator first, Iterator last) + : base(first, last) + { + } + + BOOST_DEDUCED_TYPENAME base::reference + operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) + { + return this->begin()[n]; + } + + BOOST_DEDUCED_TYPENAME base::const_reference + operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const + { + return this->begin()[n]; + } +}; + + } // namespace range_detail + + template + class sub_range + : public range_detail::sub_range_base< + ForwardRange, + BOOST_DEDUCED_TYPENAME iterator_traversal< + BOOST_DEDUCED_TYPENAME range_iterator::type + >::type + > + { + typedef BOOST_DEDUCED_TYPENAME range_iterator< + ForwardRange + >::type iterator_t; + + typedef range_detail::sub_range_base< + ForwardRange, + BOOST_DEDUCED_TYPENAME iterator_traversal< + BOOST_DEDUCED_TYPENAME range_iterator::type + >::type + > base; + + typedef BOOST_DEDUCED_TYPENAME base::impl impl; + + protected: + typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_; + + private: + template + struct is_compatible_range + : is_convertible< + BOOST_DEDUCED_TYPENAME mpl::eval_if< + has_range_iterator, + range_iterator, + mpl::identity + >::type, + BOOST_DEDUCED_TYPENAME base::iterator + > + { + }; + + public: + sub_range() + { } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) + sub_range(const sub_range& r) + : base(impl::adl_begin(static_cast(r)), + impl::adl_end(static_cast(r))) + { } +#endif + + template< class ForwardRange2 > + sub_range( + ForwardRange2& r, + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + is_compatible_range + >::type* = 0 + ) + : base(impl::adl_begin(r), impl::adl_end(r)) + { + } + + template< class ForwardRange2 > + sub_range( + const ForwardRange2& r, + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + is_compatible_range + >::type* = 0 + ) + : base(impl::adl_begin(r), impl::adl_end(r)) + { + } + + BOOST_DEDUCED_TYPENAME base::const_iterator begin() const + { + return base::begin(); + } + + BOOST_DEDUCED_TYPENAME base::iterator begin() + { + return base::begin(); + } + + BOOST_DEDUCED_TYPENAME base::const_iterator end() const + { + return base::end(); + } + + BOOST_DEDUCED_TYPENAME base::iterator end() + { + return base::end(); + } + + template< class Iter > + sub_range( Iter first, Iter last ) : + base( first, last ) + { } + + template + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + is_compatible_range, + sub_range& + >::type + operator=(ForwardRange2& r) + { + iterator_range_::operator=( r ); + return *this; + } + + template + BOOST_DEDUCED_TYPENAME ::boost::enable_if< + is_compatible_range, + sub_range& + >::type + operator=( const ForwardRange2& r ) + { + iterator_range_::operator=( r ); + return *this; + } + + sub_range& operator=( const sub_range& r ) + { + iterator_range_::operator=( static_cast(r) ); + return *this; + } + + sub_range& advance_begin( + BOOST_DEDUCED_TYPENAME base::difference_type n) + { + std::advance(this->m_Begin, n); + return *this; + } + + sub_range& advance_end( + BOOST_DEDUCED_TYPENAME base::difference_type n) + { + std::advance(this->m_End, n); + return *this; + } + }; + +} // namespace 'boost' + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) + #pragma warning( pop ) +#endif + +#endif + diff --git a/boost/range/traversal.hpp b/boost/range/traversal.hpp new file mode 100644 index 0000000..237b3e8 --- /dev/null +++ b/boost/range/traversal.hpp @@ -0,0 +1,31 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_TRAVERSAL_HPP +#define BOOST_RANGE_TRAVERSAL_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + template + struct range_traversal + : iterator_traversal::type> + { + }; +} + +#endif diff --git a/boost/range/value_type.hpp b/boost/range/value_type.hpp new file mode 100644 index 0000000..5a3187e --- /dev/null +++ b/boost/range/value_type.hpp @@ -0,0 +1,30 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#ifndef BOOST_RANGE_VALUE_TYPE_HPP +#define BOOST_RANGE_VALUE_TYPE_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +#include + +namespace boost +{ + template< class T > + struct range_value : iterator_value< typename range_iterator::type > + { }; +} + +#endif