[range] - merge the tested changes from the trunk in preparation for the 1.46 release.

[SVN r67905]
This commit is contained in:
Neil Groves
2011-01-10 06:35:02 +00:00
parent 674be9dfa0
commit 6d46ce412f
143 changed files with 5587 additions and 2015 deletions
+1
View File
@@ -76,6 +76,7 @@ namespace boost
}
} // namespace adaptors
using adaptors::sliced_range;
} // namespace boost
#endif
+217 -86
View File
@@ -16,156 +16,287 @@
#include <boost/iterator/iterator_adaptor.hpp>
#include <iterator>
#include <iostream>
namespace boost
{
namespace range_detail
{
template<class BaseIterator>
// strided_iterator for wrapping a forward traversal iterator
template<class BaseIterator, class Category>
class strided_iterator
: public iterator_adaptor<
strided_iterator<BaseIterator>
strided_iterator<BaseIterator, Category>
, BaseIterator
, use_default
, boost::forward_traversal_tag
>
{
friend class iterator_core_access;
friend class ::boost::iterator_core_access;
typedef iterator_adaptor<strided_iterator<BaseIterator>, BaseIterator> super_t;
typedef iterator_adaptor<
strided_iterator<BaseIterator, Category>
, BaseIterator
, use_default
, boost::forward_traversal_tag
> super_t;
public:
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
typedef BaseIterator base_iterator;
strided_iterator()
: m_stride(), m_offset(), m_max_offset()
: m_last()
, m_stride()
{
}
explicit strided_iterator(BaseIterator base_it,
difference_type stride,
difference_type offset,
difference_type max_offset)
: super_t(base_it)
strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
: super_t(it)
, m_last(last)
, m_stride(stride)
, m_offset(offset)
, m_max_offset(max_offset)
{
}
template<class OtherIterator>
strided_iterator(const strided_iterator<OtherIterator>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0)
strided_iterator(const strided_iterator<OtherIterator, Category>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
: super_t(other)
, m_stride(other.m_stride)
, m_offset(other.m_offset)
, m_max_offset(other.m_max_offset)
, m_last(other.base_end())
, m_stride(other.get_stride())
{
}
strided_iterator&
operator=(const strided_iterator& other)
{
super_t::operator=(other);
m_stride = other.m_stride;
m_offset = other.m_offset;
m_max_offset = other.m_max_offset;
return *this;
}
base_iterator base_end() const { return m_last; }
difference_type get_stride() const { return m_stride; }
private:
void increment()
{
m_offset += m_stride;
if (m_offset <= m_max_offset)
std::advance(this->base_reference(), m_stride);
base_iterator& it = this->base_reference();
for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
++it;
}
base_iterator m_last;
difference_type m_stride;
};
// strided_iterator for wrapping a bidirectional iterator
template<class BaseIterator>
class strided_iterator<BaseIterator, bidirectional_traversal_tag>
: public iterator_adaptor<
strided_iterator<BaseIterator, bidirectional_traversal_tag>
, BaseIterator
, use_default
, bidirectional_traversal_tag
>
{
friend class ::boost::iterator_core_access;
typedef iterator_adaptor<
strided_iterator<BaseIterator, bidirectional_traversal_tag>
, BaseIterator
, use_default
, bidirectional_traversal_tag
> super_t;
public:
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
typedef BaseIterator base_iterator;
strided_iterator()
: m_first()
, m_last()
, m_stride()
{
}
strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
: super_t(it)
, m_first(first)
, m_last(last)
, m_stride(stride)
{
}
template<class OtherIterator>
strided_iterator(const strided_iterator<OtherIterator, bidirectional_traversal_tag>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
: super_t(other.base())
, m_first(other.base_begin())
, m_last(other.base_end())
, m_stride(other.get_stride())
{
}
base_iterator base_begin() const { return m_first; }
base_iterator base_end() const { return m_last; }
difference_type get_stride() const { return m_stride; }
private:
void increment()
{
base_iterator& it = this->base_reference();
for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
++it;
}
void decrement()
{
m_offset -= m_stride;
if (m_offset >= 0)
std::advance(this->base_reference(), -m_stride);
base_iterator& it = this->base_reference();
for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i)
--it;
}
void advance(difference_type n)
{
n *= m_stride;
m_offset += n;
base_iterator m_first;
base_iterator m_last;
difference_type m_stride;
};
if (m_offset >= 0 && m_offset <= m_max_offset)
std::advance(this->base_reference(), n);
// strided_iterator implementation for wrapping a random access iterator
template<class BaseIterator>
class strided_iterator<BaseIterator, random_access_traversal_tag>
: public iterator_adaptor<
strided_iterator<BaseIterator, random_access_traversal_tag>
, BaseIterator
, use_default
, random_access_traversal_tag
>
{
friend class ::boost::iterator_core_access;
typedef iterator_adaptor<
strided_iterator<BaseIterator, random_access_traversal_tag>
, BaseIterator
, use_default
, random_access_traversal_tag
> super_t;
public:
typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type;
typedef BaseIterator base_iterator;
strided_iterator()
: m_first()
, m_last()
, m_stride()
{
}
strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride)
: super_t(it)
, m_first(first)
, m_last(last)
, m_stride(stride)
{
}
template<class OtherIterator>
bool equal(const strided_iterator<OtherIterator>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const
strided_iterator(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0)
: super_t(other.base())
, m_first(other.base_begin())
, m_last(other.base_end())
, m_stride(other.get_stride())
{
return m_offset == other.m_offset;
}
difference_type
distance_to(const strided_iterator& other) const
base_iterator base_begin() const { return m_first; }
base_iterator base_end() const { return m_last; }
difference_type get_stride() const { return m_stride; }
private:
void increment()
{
return (other.m_offset - m_offset) / m_stride;
base_iterator& it = this->base_reference();
if ((m_last - it) > m_stride)
it += m_stride;
else
it = m_last;
}
void decrement()
{
base_iterator& it = this->base_reference();
if ((it - m_first) > m_stride)
it -= m_stride;
else
it = m_first;
}
void advance(difference_type offset)
{
base_iterator& it = this->base_reference();
offset *= m_stride;
if (offset >= 0)
{
if ((m_last - it) > offset)
it += offset;
else
it = m_last;
}
else
{
if ((m_first - it) > offset)
it += offset;
else
it = m_first;
}
}
template<class OtherIterator>
difference_type distance_to(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const
{
if (other.base() >= this->base())
return (other.base() - this->base() + (m_stride - 1)) / m_stride;
return (other.base() - this->base() - (m_stride - 1)) / m_stride;
}
bool equal(const strided_iterator& other) const
{
return other.base() == this->base();
}
private:
base_iterator m_first;
base_iterator m_last;
difference_type m_stride;
difference_type m_offset;
difference_type m_max_offset;
};
template<class BaseIterator, class Difference> inline
strided_iterator<BaseIterator>
make_strided_iterator(
const BaseIterator& first,
Difference stride,
typename std::iterator_traits<BaseIterator>::difference_type offset,
typename std::iterator_traits<BaseIterator>::difference_type max_offset
)
strided_iterator<BaseIterator, BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type>
make_strided_iterator(BaseIterator first, BaseIterator it,
BaseIterator last, Difference stride)
{
BOOST_ASSERT( stride >= 0 );
BOOST_ASSERT( (stride == 0) || (offset % stride == 0) );
BOOST_ASSERT( (stride == 0) || (max_offset % stride == 0) );
BOOST_ASSERT( offset <= max_offset );
return strided_iterator<BaseIterator>(first, stride, offset, max_offset);
typedef BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type traversal_tag;
return strided_iterator<BaseIterator, traversal_tag>(first, it, last, stride);
}
template< class Rng >
template< class Rng
, class Category = BOOST_DEDUCED_TYPENAME iterator_traversal<
BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type
>::type
>
class strided_range
: public iterator_range<range_detail::strided_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> >
: public iterator_range<
range_detail::strided_iterator<
BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
Category
>
>
{
typedef range_detail::strided_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> iter_type;
typedef range_detail::strided_iterator<
BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
Category
> iter_type;
typedef iterator_range<iter_type> super_t;
public:
template<class Difference>
strided_range(Difference stride, Rng& rng)
: super_t(make_super(stride, rng))
: super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride),
make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride))
{
BOOST_ASSERT( stride >= 0 );
}
private:
template<class Difference>
static super_t make_super(const Difference stride, Rng& rng)
{
const Difference count = boost::size(rng);
const Difference max_count = max_offset(count, stride);
return super_t(make_strided_iterator(boost::begin(rng), stride, 0, max_count),
make_strided_iterator(boost::end(rng), stride, max_count, max_count));
}
template<class Difference, class Stride>
static Difference max_offset(Difference sz, const Stride stride)
{
if (stride > 0)
{
sz += stride - 1;
sz /= stride;
sz *= stride;
}
return sz;
}
};
template<class Difference>
+156 -62
View File
@@ -1,6 +1,6 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
// 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)
@@ -10,79 +10,173 @@
#ifndef BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/range_reference.hpp>
#include <boost/range/range_value.hpp>
#include <boost/range/reference.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/any_range.hpp>
#include <boost/cast.hpp>
namespace boost
{
namespace range_detail
{
template<
class Value,
class CategoryOrTraversal,
class Reference,
class Difference
>
class any_range
: public iterator_range<
IteratorTypeErasure::any_iterator<
Value, CategoryOrTraversal, Reference, Difference> >
{
typedef typename IteratorTypeErasure::any_iterator<
Value, CategoryOrTraversal, Reference, Difference> iterator_t;
typedef iterator_range<iterator_t> base_t;
public:
template<class Range>
explicit any_range(Range& r) : base_t(r) {}
template<class Range>
explicit any_range(const Range& r) : base_t(r) {}
};
template<class Range>
class any_range_generator
{
public:
typedef any_range<
BOOST_DEDUCED_TYPENAME range_value<Range>::type,
BOOST_DEDUCED_TYPENAME iterator_traversal<
BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
>::type,
BOOST_DEDUCED_TYPENAME range_reference<Range>::type,
BOOST_DEDUCED_TYPENAME range_difference<Range>::type
> type;
};
class type_erased_tag {};
} // namespace range_detail
using range_detail::any_range;
namespace adaptors
{
namespace
template<
class Value = use_default
, class Traversal = use_default
, class Reference = use_default
, class Difference = use_default
, class Buffer = use_default
>
struct type_erased
{
const range_detail::type_erased_tag type_erased = range_detail::type_erased_tag();
};
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
>)
{
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>
typename range_detail::any_range_generator<SinglePassRange>::type
operator|(SinglePassRange& rng, range_detail::type_erased_tag)
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
>)
{
typedef typename range_detail::any_range_generator<SinglePassRange>::type range_t;
return range_t(rng);
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>
typename range_detail::any_range_generator<const SinglePassRange>::type
operator|(const SinglePassRange& rng, range_detail::type_erased_tag)
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<>()
)
{
typedef typename range_detail::any_range_generator<const SinglePassRange>::type range_t;
return range_t(rng);
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<>()
)
{
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
+204
View File
@@ -0,0 +1,204 @@
// Copyright Neil Groves 2010. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/range/detail/any_iterator.hpp>
#include <boost/range/reference.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/cast.hpp>
namespace boost
{
namespace range_detail
{
// If T is use_default, return the result of Default, otherwise
// return T.
//
// This is an implementation artifact used to pick intelligent default
// values when the user specified boost::use_default as a template
// parameter.
template<
class T,
class Default
>
struct any_range_default_help
: mpl::eval_if<
is_same<T, use_default>
, Default
, mpl::identity<T>
>
{
};
template<
class WrappedRange
, class Value
, class Reference
>
struct any_range_value_type
{
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
typedef typename any_range_default_help<
Value
, mpl::eval_if<
is_same<Reference, use_default>
, range_value<
typename remove_const<WrappedRange>
::type>
, remove_reference<Reference>
>
>::type type;
# else
typedef typename any_range_default_help<
Value
, range_value<
typename remove_const<WrappedRange>
::type>
>::type type;
# endif
};
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer = use_default
>
class any_range
: public iterator_range<
any_iterator<
Value
, Traversal
, Reference
, Difference
, typename any_range_default_help<
Buffer
, mpl::identity<any_iterator_default_buffer>
>::type
>
>
{
typedef iterator_range<
any_iterator<
Value
, Traversal
, Reference
, Difference
, typename any_range_default_help<
Buffer
, mpl::identity<any_iterator_default_buffer>
>::type
>
> base_type;
struct enabler {};
struct disabler {};
public:
any_range()
{
}
any_range(const any_range& other)
: base_type(other)
{
}
template<class WrappedRange>
any_range(WrappedRange& wrapped_range)
: base_type(boost::begin(wrapped_range),
boost::end(wrapped_range))
{
}
template<class WrappedRange>
any_range(const WrappedRange& wrapped_range)
: base_type(boost::begin(wrapped_range),
boost::end(wrapped_range))
{
}
template<
class OtherValue
, class OtherTraversal
, class OtherReference
, class OtherDifference
>
any_range(const any_range<
OtherValue
, OtherTraversal
, OtherReference
, OtherDifference
, Buffer
>& other)
: base_type(boost::begin(other), boost::end(other))
{
}
template<class Iterator>
any_range(Iterator first, Iterator last)
: base_type(first, last)
{
}
};
template<
class WrappedRange
, class Value = use_default
, class Traversal = use_default
, class Reference = use_default
, class Difference = use_default
, class Buffer = use_default
>
struct any_range_type_generator
{
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<WrappedRange> ));
typedef any_range<
typename any_range_value_type<
WrappedRange
, Value
, typename any_range_default_help<
Reference
, range_reference<WrappedRange>
>::type
>::type
, typename any_range_default_help<
Traversal
, iterator_traversal<
typename range_iterator<WrappedRange>::type
>
>::type
, typename any_range_default_help<
Reference
, range_reference<WrappedRange>
>::type
, typename any_range_default_help<
Difference
, range_difference<WrappedRange>
>::type
, typename any_range_default_help<
Buffer
, mpl::identity<any_iterator_default_buffer>
>::type
> type;
};
} // namespace range_detail
using range_detail::any_range;
using range_detail::any_range_type_generator;
} // namespace boost
#endif // include guard
+17 -6
View File
@@ -91,6 +91,11 @@ namespace range_detail
} // namespace 'range_detail'
#endif
// Use a ADL namespace barrier to avoid ambiguity with other unqualified
// calls. This is particularly important with C++0x encouraging
// unqualified calls to begin/end.
namespace range_adl_barrier
{
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
@@ -114,19 +119,25 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
return range_begin( r );
}
} // namespace range_adl_barrier
} // namespace boost
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
namespace boost
{
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
const_begin( const T& r )
namespace range_adl_barrier
{
return boost::begin( r );
}
}
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
const_begin( const T& r )
{
return boost::range_adl_barrier::begin( r );
}
} // namespace range_adl_barrier
using namespace range_adl_barrier;
} // namespace boost
#endif
+20 -3
View File
@@ -148,13 +148,16 @@ namespace boost {
Iterator i2(++i);
boost::ignore_unused_variable_warning(i2);
Iterator i3(i++);
boost::ignore_unused_variable_warning(i3);
// deliberately we are loose with the postfix version for the single pass
// iterator due to the commonly poor adherence to the specification means that
// many algorithms would be unusable, whereas actually without the check they
// work
(void)(i++);
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r1(*i);
boost::ignore_unused_variable_warning(r1);
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r2(*i++);
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r2(*(++i));
boost::ignore_unused_variable_warning(r2);
}
private:
@@ -178,6 +181,20 @@ namespace boost {
BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
forward_traversal_tag
>));
BOOST_CONCEPT_USAGE(ForwardIteratorConcept)
{
// See the above note in the SinglePassIteratorConcept about the handling of the
// postfix increment. Since with forward and better iterators there is no need
// for a proxy, we can sensibly require that the dereference result
// is convertible to reference.
Iterator i2(i++);
boost::ignore_unused_variable_warning(i2);
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r(*(i++));
boost::ignore_unused_variable_warning(r);
}
private:
Iterator i;
#endif
};
+587
View File
@@ -0,0 +1,587 @@
// Boost.Range library
//
// Copyright Neil Groves 2010. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
#include <boost/cast.hpp>
#include <boost/utility.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/range/detail/any_iterator_buffer.hpp>
#include <boost/range/detail/any_iterator_interface.hpp>
#include <boost/range/detail/any_iterator_wrapper.hpp>
namespace boost
{
namespace range_detail
{
// metafunction to determine if T is a const reference
template<class T>
struct is_const_reference
{
typedef typename mpl::and_<
typename is_reference<T>::type,
typename is_const<
typename remove_reference<T>::type
>::type
>::type type;
};
// metafunction to determine if T is a mutable reference
template<class T>
struct is_mutable_reference
{
typedef typename mpl::and_<
typename is_reference<T>::type,
typename mpl::not_<
typename is_const<
typename remove_reference<T>::type
>::type
>::type
>::type type;
};
// metafunction to evaluate if a source 'reference' can be
// converted to a target 'reference' as a value.
//
// This is true, when the target reference type is actually
// not a reference, and the source reference is convertible
// to the target type.
template<class SourceReference, class TargetReference>
struct is_convertible_to_value_as_reference
{
typedef typename mpl::and_<
typename mpl::not_<
typename is_reference<TargetReference>::type
>::type
, typename is_convertible<
SourceReference
, TargetReference
>::type
>::type type;
};
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer = any_iterator_default_buffer
>
class any_iterator;
// metafunction to determine if SomeIterator is an
// any_iterator.
//
// This is the general implementation which evaluates to false.
template<class SomeIterator>
struct is_any_iterator
: mpl::bool_<false>
{
};
// specialization of is_any_iterator to return true for
// any_iterator classes regardless of template parameters.
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer
>
struct is_any_iterator<
any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
>
>
: mpl::bool_<true>
{
};
} // namespace range_detail
namespace detail
{
// Rationale:
// These are specialized since the iterator_facade versions lack
// the requisite typedefs to allow wrapping to determine the types
// if a user copy constructs from a postfix increment.
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer
>
class postfix_increment_proxy<
range_detail::any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
>
>
{
typedef range_detail::any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
> any_iterator_type;
public:
typedef Value value_type;
typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
typedef Difference difference_type;
typedef typename iterator_pointer<any_iterator_type>::type pointer;
typedef Reference reference;
explicit postfix_increment_proxy(any_iterator_type const& x)
: stored_value(*x)
{}
value_type&
operator*() const
{
return this->stored_value;
}
private:
mutable value_type stored_value;
};
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer
>
class writable_postfix_increment_proxy<
range_detail::any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
>
>
{
typedef range_detail::any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
> any_iterator_type;
public:
typedef Value value_type;
typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
typedef Difference difference_type;
typedef typename iterator_pointer<any_iterator_type>::type pointer;
typedef Reference reference;
explicit writable_postfix_increment_proxy(any_iterator_type const& x)
: stored_value(*x)
, stored_iterator(x)
{}
// Dereferencing must return a proxy so that both *r++ = o and
// value_type(*r++) can work. In this case, *r is the same as
// *r++, and the conversion operator below is used to ensure
// readability.
writable_postfix_increment_proxy const&
operator*() const
{
return *this;
}
// Provides readability of *r++
operator value_type&() const
{
return stored_value;
}
// Provides writability of *r++
template <class T>
T const& operator=(T const& x) const
{
*this->stored_iterator = x;
return x;
}
// This overload just in case only non-const objects are writable
template <class T>
T& operator=(T& x) const
{
*this->stored_iterator = x;
return x;
}
// Provides X(r++)
operator any_iterator_type const&() const
{
return stored_iterator;
}
private:
mutable value_type stored_value;
any_iterator_type stored_iterator;
};
}
namespace range_detail
{
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer
>
class any_iterator
: public iterator_facade<
any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
>
, Value
, Traversal
, Reference
, Difference
>
{
template<
class OtherValue
, class OtherTraversal
, class OtherReference
, class OtherDifference
, class OtherBuffer
>
friend class any_iterator;
struct enabler {};
struct disabler {};
typedef typename any_iterator_interface_type_generator<
Traversal
, Reference
, Difference
, Buffer
>::type abstract_base_type;
typedef iterator_facade<
any_iterator<
Value
, Traversal
, Reference
, Difference
, Buffer
>
, Value
, Traversal
, Reference
, Difference
> base_type;
typedef Buffer buffer_type;
public:
typedef typename base_type::value_type value_type;
typedef typename base_type::reference reference;
typedef typename base_type::difference_type difference_type;
// Default constructor
any_iterator()
: m_impl(0) {}
// Simple copy construction without conversion
any_iterator(const any_iterator& other)
: base_type(other)
, m_impl(other.m_impl
? other.m_impl->clone(m_buffer)
: 0)
{
}
// Simple assignment operator without conversion
any_iterator& operator=(const any_iterator& other)
{
if (this != &other)
{
if (m_impl)
m_impl->~abstract_base_type();
m_buffer.deallocate();
m_impl = 0;
if (other.m_impl)
m_impl = other.m_impl->clone(m_buffer);
}
return *this;
}
// Implicit conversion from another any_iterator where the
// conversion is from a non-const reference to a const reference
template<
class OtherValue
, class OtherTraversal
, class OtherReference
, class OtherDifference
>
any_iterator(const any_iterator<
OtherValue,
OtherTraversal,
OtherReference,
OtherDifference,
Buffer
>& other,
typename enable_if<
typename mpl::and_<
typename is_mutable_reference<OtherReference>::type,
typename is_const_reference<Reference>::type
>::type,
enabler
>::type* = 0
)
: m_impl(other.m_impl
? other.m_impl->clone_const_ref(m_buffer)
: 0
)
{
}
// Implicit conversion from another any_iterator where the
// reference types of the source and the target are references
// that are either both const, or both non-const.
template<
class OtherValue
, class OtherTraversal
, class OtherReference
, class OtherDifference
>
any_iterator(const any_iterator<
OtherValue
, OtherTraversal
, OtherReference
, OtherDifference
, Buffer
>& other,
typename enable_if<
typename mpl::or_<
typename mpl::and_<
typename is_mutable_reference<OtherReference>::type,
typename is_mutable_reference<Reference>::type
>::type,
typename mpl::and_<
typename is_const_reference<OtherReference>::type,
typename is_const_reference<Reference>::type
>::type
>::type,
enabler
>::type* = 0
)
: m_impl(other.m_impl
? other.m_impl->clone(m_buffer)
: 0
)
{
}
// Implicit conversion to an any_iterator that uses a value for
// the reference type.
template<
class OtherValue
, class OtherTraversal
, class OtherReference
, class OtherDifference
>
any_iterator(const any_iterator<
OtherValue
, OtherTraversal
, OtherReference
, OtherDifference
, Buffer
>& other,
typename enable_if<
typename is_convertible_to_value_as_reference<
OtherReference
, Reference
>::type,
enabler
>::type* = 0
)
: m_impl(other.m_impl
? other.m_impl->clone_reference_as_value(m_buffer)
: 0
)
{
}
any_iterator clone() const
{
any_iterator result;
if (m_impl)
result.m_impl = m_impl->clone(result.m_buffer);
return result;
}
any_iterator<
Value
, Traversal
, typename abstract_base_type::const_reference
, Difference
, Buffer
>
clone_const_ref() const
{
typedef any_iterator<
Value
, Traversal
, typename abstract_base_type::const_reference
, Difference
, Buffer
> result_type;
result_type result;
if (m_impl)
result.m_impl = m_impl->clone_const_ref(result.m_buffer);
return result;
}
// implicit conversion and construction from type-erasure-compatible
// iterators
template<class WrappedIterator>
explicit any_iterator(
const WrappedIterator& wrapped_iterator,
typename disable_if<
typename is_any_iterator<WrappedIterator>::type
, disabler
>::type* = 0
)
{
typedef typename any_iterator_wrapper_type_generator<
WrappedIterator
, Traversal
, Reference
, Difference
, Buffer
>::type wrapper_type;
void* ptr = m_buffer.allocate(sizeof(wrapper_type));
m_impl = new(ptr) wrapper_type(wrapped_iterator);
}
~any_iterator()
{
// manually run the destructor, the deallocation is automatically
// handled by the any_iterator_small_buffer base class.
if (m_impl)
m_impl->~abstract_base_type();
}
private:
friend class ::boost::iterator_core_access;
Reference dereference() const
{
BOOST_ASSERT( m_impl );
return m_impl->dereference();
}
bool equal(const any_iterator& other) const
{
return (m_impl == other.m_impl)
|| (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
}
void increment()
{
BOOST_ASSERT( m_impl );
m_impl->increment();
}
void decrement()
{
BOOST_ASSERT( m_impl );
m_impl->decrement();
}
Difference distance_to(const any_iterator& other) const
{
return m_impl && other.m_impl
? m_impl->distance_to(*other.m_impl)
: 0;
}
void advance(Difference offset)
{
BOOST_ASSERT( m_impl );
m_impl->advance(offset);
}
any_iterator& swap(any_iterator& other)
{
BOOST_ASSERT( this != &other );
// grab a temporary copy of the other iterator
any_iterator tmp(other);
// deallocate the other iterator, taking care to obey the
// class-invariants in-case of exceptions later
if (other.m_impl)
{
other.m_impl->~abstract_base_type();
other.m_buffer.deallocate();
other.m_impl = 0;
}
// If this is a non-null iterator then we need to put
// a clone of this iterators impementation 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
@@ -0,0 +1,117 @@
// Boost.Range library
//
// Copyright Neil Groves 2010. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
#include <boost/array.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/utility.hpp>
namespace boost
{
template<std::size_t StackBufferSize>
class any_iterator_buffer
: noncopyable
{
BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
public:
any_iterator_buffer()
: m_ptr()
{
}
~any_iterator_buffer()
{
delete [] m_ptr;
}
void* allocate(std::size_t bytes)
{
BOOST_ASSERT( !m_ptr );
if (bytes <= StackBufferSize)
return m_buffer.data();
m_ptr = new char[bytes];
return m_ptr;
}
void deallocate()
{
delete [] m_ptr;
m_ptr = 0;
}
private:
// Rationale:
// Do not use inheritance from noncopyable because this causes
// the concepts to erroneous detect the derived any_iterator
// as noncopyable.
any_iterator_buffer(const any_iterator_buffer&);
void operator=(const any_iterator_buffer&);
char* m_ptr;
boost::array<char, StackBufferSize> m_buffer;
};
class any_iterator_heap_only_buffer
: noncopyable
{
public:
any_iterator_heap_only_buffer()
: m_ptr()
{
}
~any_iterator_heap_only_buffer()
{
delete [] m_ptr;
}
void* allocate(std::size_t bytes)
{
BOOST_ASSERT( !m_ptr );
m_ptr = new char[bytes];
return m_ptr;
}
void deallocate()
{
delete [] m_ptr;
m_ptr = 0;
}
private:
char* m_ptr;
};
template<std::size_t StackBufferSize>
class any_iterator_stack_only_buffer
{
BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
public:
void* allocate(std::size_t bytes)
{
BOOST_ASSERT( bytes <= m_buffer.size() );
return m_buffer.data();
}
void deallocate()
{
}
private:
boost::array<char, StackBufferSize> m_buffer;
};
typedef any_iterator_buffer<64> any_iterator_default_buffer;
} // namespace boost
#endif // include guard
@@ -0,0 +1,258 @@
// Boost.Range library
//
// Copyright Neil Groves 2010. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
#include <boost/range/detail/any_iterator_buffer.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp>
namespace boost
{
namespace range_detail
{
template<class T>
struct const_reference_type_generator
{
typedef typename mpl::if_<
typename is_reference<T>::type,
typename add_reference<
typename add_const<
typename remove_reference<T>::type
>::type
>::type,
T
>::type type;
};
template<
class Reference
, class Buffer
>
struct any_incrementable_iterator_interface
{
typedef Reference reference;
typedef typename const_reference_type_generator<
Reference
>::type const_reference;
typedef typename remove_const<
typename remove_reference<Reference>::type
>::type reference_as_value_type;
typedef Buffer buffer_type;
virtual ~any_incrementable_iterator_interface() {}
virtual any_incrementable_iterator_interface*
clone(buffer_type& buffer) const = 0;
virtual any_incrementable_iterator_interface<const_reference, Buffer>*
clone_const_ref(buffer_type& buffer) const = 0;
virtual any_incrementable_iterator_interface<reference_as_value_type, Buffer>*
clone_reference_as_value(buffer_type& buffer) const = 0;
virtual void increment() = 0;
};
template<
class Reference
, class Buffer
>
struct any_single_pass_iterator_interface
: any_incrementable_iterator_interface<Reference, Buffer>
{
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference reference;
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::const_reference const_reference;
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
virtual any_single_pass_iterator_interface*
clone(buffer_type& buffer) const = 0;
virtual any_single_pass_iterator_interface<const_reference, Buffer>*
clone_const_ref(buffer_type& buffer) const = 0;
virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
clone_reference_as_value(buffer_type& buffer) const = 0;
virtual Reference dereference() const = 0;
virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
};
template<
class Reference
, class Buffer
>
struct any_forward_iterator_interface
: any_single_pass_iterator_interface<Reference, Buffer>
{
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference reference;
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::const_reference const_reference;
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
virtual any_forward_iterator_interface*
clone(buffer_type& buffer) const = 0;
virtual any_forward_iterator_interface<const_reference, Buffer>*
clone_const_ref(buffer_type& buffer) const = 0;
virtual any_forward_iterator_interface<reference_as_value_type, Buffer>*
clone_reference_as_value(buffer_type& buffer) const = 0;
};
template<
class Reference
, class Buffer
>
struct any_bidirectional_iterator_interface
: any_forward_iterator_interface<Reference, Buffer>
{
typedef typename any_forward_iterator_interface<Reference, Buffer>::reference reference;
typedef typename any_forward_iterator_interface<Reference, Buffer>::const_reference const_reference;
typedef typename any_forward_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
typedef typename any_forward_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
virtual any_bidirectional_iterator_interface*
clone(buffer_type& buffer) const = 0;
virtual any_bidirectional_iterator_interface<const_reference, Buffer>*
clone_const_ref(buffer_type& buffer) const = 0;
virtual any_bidirectional_iterator_interface<reference_as_value_type, Buffer>*
clone_reference_as_value(buffer_type& buffer) const = 0;
virtual void decrement() = 0;
};
template<
class Reference
, class Difference
, class Buffer
>
struct any_random_access_iterator_interface
: any_bidirectional_iterator_interface<
Reference
, Buffer
>
{
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference reference;
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::const_reference const_reference;
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
typedef Difference difference_type;
virtual any_random_access_iterator_interface*
clone(buffer_type& buffer) const = 0;
virtual any_random_access_iterator_interface<const_reference, Difference, Buffer>*
clone_const_ref(buffer_type& buffer) const = 0;
virtual any_random_access_iterator_interface<reference_as_value_type, Difference, Buffer>*
clone_reference_as_value(buffer_type& buffer) const = 0;
virtual void advance(Difference offset) = 0;
virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0;
};
template<
class Traversal
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_interface_type_generator;
template<
class Reference
, class Difference
, class Buffer
>
struct any_iterator_interface_type_generator<
incrementable_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_incrementable_iterator_interface<Reference, Buffer> type;
};
template<
class Reference
, class Difference
, class Buffer
>
struct any_iterator_interface_type_generator<
single_pass_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_single_pass_iterator_interface<Reference, Buffer> type;
};
template<
class Reference
, class Difference
, class Buffer
>
struct any_iterator_interface_type_generator<
forward_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_forward_iterator_interface<Reference, Buffer> type;
};
template<
class Reference
, class Difference
, class Buffer
>
struct any_iterator_interface_type_generator<
bidirectional_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_bidirectional_iterator_interface<Reference, Buffer> type;
};
template<
class Reference
, class Difference
, class Buffer
>
struct any_iterator_interface_type_generator<
random_access_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_random_access_iterator_interface<
Reference
, Difference
, Buffer
> type;
};
} // namespace range_detail
} // namespace boost
#endif // include guard
@@ -0,0 +1,590 @@
// Boost.Range library
//
// Copyright Neil Groves 2010. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
#include <boost/range/config.hpp>
#include <boost/range/detail/any_iterator_interface.hpp>
namespace boost
{
namespace range_detail
{
template<
class WrappedIterator
, class Reference
, class Buffer
>
class any_incrementable_iterator_wrapper
: public any_incrementable_iterator_interface<
Reference
, Buffer
>
{
BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept<WrappedIterator> ));
public:
typedef WrappedIterator wrapped_type;
BOOST_STATIC_ASSERT(( is_convertible<
typename iterator_reference<WrappedIterator>::type
, Reference
>::value ));
any_incrementable_iterator_wrapper()
: m_it()
{}
explicit any_incrementable_iterator_wrapper(wrapped_type it)
: m_it(it)
{}
// any_incrementable_iterator implementation
virtual any_incrementable_iterator_wrapper* clone(
typename any_incrementable_iterator_wrapper::buffer_type& buffer
) const
{
return new (buffer.allocate(sizeof(*this)))
any_incrementable_iterator_wrapper(m_it);
}
virtual any_incrementable_iterator_wrapper<
WrappedIterator
, typename any_incrementable_iterator_wrapper::const_reference
, Buffer
>* clone_const_ref(
typename any_incrementable_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_incrementable_iterator_wrapper<
WrappedIterator
, typename any_incrementable_iterator_wrapper::const_reference
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual any_incrementable_iterator_wrapper<
WrappedIterator
, typename any_incrementable_iterator_wrapper::reference_as_value_type
, Buffer
>* clone_reference_as_value(
typename any_incrementable_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_incrementable_iterator_wrapper<
WrappedIterator
, typename any_incrementable_iterator_wrapper::reference_as_value_type
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual void increment()
{
++m_it;
}
private:
wrapped_type m_it;
};
template<
class WrappedIterator
, class Reference
, class Buffer
>
class any_single_pass_iterator_wrapper
: public any_single_pass_iterator_interface<
Reference
, Buffer
>
{
struct disabler {};
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
public:
any_single_pass_iterator_wrapper()
: m_it()
{}
explicit any_single_pass_iterator_wrapper(const WrappedIterator& it)
: m_it(it)
{}
// any_single_pass_iterator_interface<Reference> implementation
virtual any_single_pass_iterator_wrapper* clone(
typename any_single_pass_iterator_wrapper::buffer_type& buffer
) const
{
return new (buffer.allocate(sizeof(*this)))
any_single_pass_iterator_wrapper(m_it);
}
virtual any_single_pass_iterator_wrapper<
WrappedIterator
, typename any_single_pass_iterator_wrapper::const_reference
, Buffer
>* clone_const_ref(
typename any_single_pass_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_single_pass_iterator_wrapper<
WrappedIterator
, typename any_single_pass_iterator_wrapper::const_reference
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual any_single_pass_iterator_wrapper<
WrappedIterator
, typename any_single_pass_iterator_wrapper::reference_as_value_type
, Buffer
>* clone_reference_as_value(
typename any_single_pass_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_single_pass_iterator_wrapper<
WrappedIterator
, typename any_single_pass_iterator_wrapper::reference_as_value_type
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual void increment()
{
++m_it;
}
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
{
return m_it == boost::polymorphic_downcast<const any_single_pass_iterator_wrapper*>(&other)->m_it;
}
virtual Reference dereference() const
{
return *m_it;
}
private:
WrappedIterator m_it;
};
template<
class WrappedIterator
, class Reference
, class Buffer
>
class any_forward_iterator_wrapper
: public any_forward_iterator_interface<
Reference
, Buffer
>
{
BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
public:
any_forward_iterator_wrapper()
: m_it()
{}
explicit any_forward_iterator_wrapper(const WrappedIterator& it)
: m_it(it)
{}
// any_forward_iterator_interface<Reference> implementation
virtual any_forward_iterator_wrapper* clone(
typename any_forward_iterator_wrapper::buffer_type& buffer
) const
{
return new (buffer.allocate(sizeof(*this)))
any_forward_iterator_wrapper(m_it);
}
virtual any_forward_iterator_wrapper<
WrappedIterator
, typename any_forward_iterator_wrapper::const_reference
, Buffer
>* clone_const_ref(
typename any_forward_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_forward_iterator_wrapper<
WrappedIterator
, typename any_forward_iterator_wrapper::const_reference
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual any_forward_iterator_wrapper<
WrappedIterator
, typename any_forward_iterator_wrapper::reference_as_value_type
, Buffer
>* clone_reference_as_value(
typename any_forward_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_forward_iterator_wrapper<
WrappedIterator
, typename any_forward_iterator_wrapper::reference_as_value_type
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual void increment()
{
++m_it;
}
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
{
return m_it == boost::polymorphic_downcast<const any_forward_iterator_wrapper*>(&other)->m_it;
}
virtual Reference dereference() const
{
return *m_it;
}
private:
WrappedIterator m_it;
};
template<
class WrappedIterator
, class Reference
, class Buffer
>
class any_bidirectional_iterator_wrapper
: public any_bidirectional_iterator_interface<
Reference
, Buffer
>
{
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
public:
any_bidirectional_iterator_wrapper()
: m_it()
{
}
explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it)
: m_it(it)
{
}
virtual any_bidirectional_iterator_wrapper* clone(
typename any_bidirectional_iterator_wrapper::buffer_type& buffer
) const
{
return new (buffer.allocate(sizeof(*this)))
any_bidirectional_iterator_wrapper(*this);
}
virtual any_bidirectional_iterator_wrapper<
WrappedIterator
, typename any_bidirectional_iterator_wrapper::const_reference
, Buffer
>* clone_const_ref(
typename any_bidirectional_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_bidirectional_iterator_wrapper<
WrappedIterator
, typename any_bidirectional_iterator_wrapper::const_reference
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual any_bidirectional_iterator_wrapper<
WrappedIterator
, typename any_bidirectional_iterator_wrapper::reference_as_value_type
, Buffer
>* clone_reference_as_value(
typename any_bidirectional_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_bidirectional_iterator_wrapper<
WrappedIterator
, typename any_bidirectional_iterator_wrapper::reference_as_value_type
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual void increment()
{
++m_it;
}
virtual void decrement()
{
--m_it;
}
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
{
return m_it == boost::polymorphic_downcast<const any_bidirectional_iterator_wrapper*>(&other)->m_it;
}
virtual Reference dereference() const
{
return *m_it;
}
private:
WrappedIterator m_it;
};
template<
class WrappedIterator
, class Reference
, class Difference
, class Buffer
>
class any_random_access_iterator_wrapper
: public any_random_access_iterator_interface<
Reference
, Difference
, Buffer
>
{
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
public:
typedef Difference difference_type;
any_random_access_iterator_wrapper()
: m_it()
{
}
explicit any_random_access_iterator_wrapper(const WrappedIterator& other)
: m_it(other)
{
}
virtual any_random_access_iterator_wrapper* clone(
typename any_random_access_iterator_wrapper::buffer_type& buffer
) const
{
return new (buffer.allocate(sizeof(*this)))
any_random_access_iterator_wrapper(*this);
}
virtual any_random_access_iterator_wrapper<
WrappedIterator
, typename any_random_access_iterator_wrapper::const_reference
, Difference
, Buffer
>* clone_const_ref(
typename any_random_access_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_random_access_iterator_wrapper<
WrappedIterator
, typename any_random_access_iterator_wrapper::const_reference
, Difference
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual any_random_access_iterator_wrapper<
WrappedIterator
, typename any_random_access_iterator_wrapper::reference_as_value_type
, Difference
, Buffer
>* clone_reference_as_value(
typename any_random_access_iterator_wrapper::buffer_type& buffer
) const
{
typedef any_random_access_iterator_wrapper<
WrappedIterator
, typename any_random_access_iterator_wrapper::reference_as_value_type
, Difference
, Buffer
> result_type;
return new (buffer.allocate(sizeof(result_type)))
result_type(m_it);
}
virtual void increment()
{
++m_it;
}
virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
{
return m_it == boost::polymorphic_downcast<const any_random_access_iterator_wrapper*>(&other)->m_it;
}
virtual void decrement()
{
--m_it;
}
virtual void advance(Difference offset)
{
m_it += offset;
}
virtual Reference dereference() const
{
return *m_it;
}
virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
{
return boost::polymorphic_downcast<const any_random_access_iterator_wrapper*>(&other)->m_it - m_it;
}
private:
WrappedIterator m_it;
};
template<
class WrappedIterator
, class Traversal
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_wrapper_type_generator;
template<
class WrappedIterator
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_wrapper_type_generator<
WrappedIterator
, incrementable_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_incrementable_iterator_wrapper<
WrappedIterator
, Reference
, Buffer
> type;
};
template<
class WrappedIterator
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_wrapper_type_generator<
WrappedIterator
, single_pass_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_single_pass_iterator_wrapper<
WrappedIterator
, Reference
, Buffer
> type;
};
template<
class WrappedIterator
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_wrapper_type_generator<
WrappedIterator
, forward_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_forward_iterator_wrapper<
WrappedIterator
, Reference
, Buffer
> type;
};
template<
class WrappedIterator
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_wrapper_type_generator<
WrappedIterator
, bidirectional_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_bidirectional_iterator_wrapper<
WrappedIterator
, Reference
, Buffer
> type;
};
template<
class WrappedIterator
, class Reference
, class Difference
, class Buffer
>
struct any_iterator_wrapper_type_generator<
WrappedIterator
, random_access_traversal_tag
, Reference
, Difference
, Buffer
>
{
typedef any_random_access_iterator_wrapper<
WrappedIterator
, Reference
, Difference
, Buffer
> type;
};
} // namespace range_detail
} // namespace boost
#endif // include guard
+15 -13
View File
@@ -19,9 +19,9 @@
# include <boost/range/value_type.hpp>
#endif
namespace boost
namespace boost
{
namespace range_detail
{
template< typename T >
@@ -30,7 +30,7 @@ namespace boost
//////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////
template<>
struct range_begin<std_container_>
{
@@ -40,11 +40,11 @@ namespace boost
return c.begin();
};
};
//////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////
template<>
struct range_begin<std_pair_>
{
@@ -54,11 +54,11 @@ namespace boost
return p.first;
}
};
//////////////////////////////////////////////////////////////////////
// array
//////////////////////////////////////////////////////////////////////
template<>
struct range_begin<array_>
{
@@ -78,14 +78,16 @@ namespace boost
};
} // namespace 'range_detail'
template< typename C >
inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
begin( C& c )
namespace range_adl_barrier
{
return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
template< typename C >
inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
begin( C& c )
{
return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
}
}
} // namespace 'boost'
+20 -17
View File
@@ -24,7 +24,7 @@
# include <boost/range/detail/remove_extent.hpp>
# endif
namespace boost
namespace boost
{
namespace range_detail
{
@@ -34,39 +34,39 @@ namespace boost
//////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////
template<>
struct range_end<std_container_>
{
template< typename C >
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
fun( C& c )
{
return c.end();
};
};
//////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////
template<>
struct range_end<std_pair_>
{
template< typename P >
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
fun( const P& p )
{
return p.second;
}
};
//////////////////////////////////////////////////////////////////////
// array
//////////////////////////////////////////////////////////////////////
template<>
struct range_end<array_>
struct range_end<array_>
{
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
template< typename T, std::size_t sz >
@@ -82,16 +82,19 @@ namespace boost
}
#endif
};
} // namespace 'range_detail'
template< typename C >
inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
end( C& c )
namespace range_adl_barrier
{
return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
}
template< typename C >
inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
end( C& c )
{
return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
}
} // namespace range_adl_barrier
} // namespace 'boost'
# endif // VC6
+72
View File
@@ -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
// <boost/smart_ptr/operator_bool.hpp>
#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
#include <boost/config.hpp>
#include <boost/range/config.hpp>
namespace boost
{
namespace range_detail
{
template<class DataMemberPtr>
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
+14 -9
View File
@@ -88,6 +88,9 @@ namespace range_detail
} // namespace 'range_detail'
#endif
namespace range_adl_barrier
{
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
{
@@ -110,22 +113,24 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
return range_end( r );
}
} // namespace range_adl_barrier
} // namespace 'boost'
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
namespace boost
{
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
const_end( const T& r )
namespace range_adl_barrier
{
return boost::end( r );
}
}
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::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
+9 -11
View File
@@ -27,6 +27,7 @@
#include <boost/range/iterator.hpp>
#include <boost/range/difference_type.hpp>
#include <boost/range/algorithm/equal.hpp>
#include <boost/range/detail/safe_bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <iterator>
#include <algorithm>
@@ -81,7 +82,6 @@ namespace boost
struct range_tag { };
struct const_range_tag { };
}
// iterator range template class -----------------------------------------//
@@ -106,13 +106,14 @@ namespace boost
template<class IteratorT>
class iterator_range
{
typedef range_detail::safe_bool< IteratorT iterator_range<IteratorT>::* > safe_bool_t;
protected: // Used by sub_range
//! implementation class
typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
public:
//! this type
typedef iterator_range<IteratorT> type;
typedef BOOST_DEDUCED_TYPENAME safe_bool_t::unspecified_bool_type unspecified_bool_type;
//BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type);
//! Encapsulated value type
@@ -238,18 +239,15 @@ namespace boost
return m_Begin == m_End;
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
operator bool() const
{
return !empty();
}
#else
typedef iterator (iterator_range::*unspecified_bool_type) () const;
operator unspecified_bool_type() const
{
return empty() ? 0: &iterator_range::end;
return safe_bool_t::to_unspecified_bool(m_Begin != m_End, &iterator_range::m_Begin);
}
bool operator!() const
{
return empty();
}
#endif
bool equal( const iterator_range& r ) const
{
+8 -27
View File
@@ -15,7 +15,7 @@
# pragma once
#endif
#include <boost/iterator/iterator_categories.hpp>
#include <boost/range/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/difference_type.hpp>
@@ -25,44 +25,25 @@ namespace boost
{
namespace range_detail
{
template< class SinglePassRange >
template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
size_impl(const SinglePassRange& rng, boost::single_pass_traversal_tag)
{
typedef BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type diff_t;
// A compilation error here will often indicate that an algorithm
// is attempting to use boost::size(rng) for a range that is not a
// model of the RandomAccessRange Concept and does not have a
// member size() function.
// The solution to this issue is to add a range_calculate_size()
// function for the range type that will be found via ADL.
return static_cast<diff_t>(rng.size());
}
template< class SinglePassRange >
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
size_impl(const SinglePassRange& rng, boost::random_access_traversal_tag)
range_calculate_size(const SinglePassRange& rng)
{
BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 &&
"reachability invariant broken!" );
return boost::end(rng) - boost::begin(rng);
}
} // namespace range_detail
template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
range_calculate_size(const SinglePassRange& rng)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type iter_t;
typedef BOOST_DEDUCED_TYPENAME iterator_traversal<iter_t>::type traversal_tag;
return range_detail::size_impl(rng, traversal_tag());
}
template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::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);
}