forked from boostorg/range
[boost][range] - Updated begin/end to be protected against accidental ADL to improve compatibility with C++0x. Added any_range which adds type erasure support. Added a type_erased adaptor to utilise the any_range. Implemented the any_iterator using a small buffer optimization to avoid heap usage.
[SVN r67541]
This commit is contained in:
@ -76,6 +76,7 @@ namespace boost
|
||||
}
|
||||
|
||||
} // namespace adaptors
|
||||
using adaptors::sliced_range;
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
@ -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
include/boost/range/any_range.hpp
Normal file
204
include/boost/range/any_range.hpp
Normal 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
|
@ -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
|
||||
|
||||
|
@ -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
include/boost/range/detail/any_iterator.hpp
Normal file
587
include/boost/range/detail/any_iterator.hpp
Normal 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
|
119
include/boost/range/detail/any_iterator_buffer.hpp
Normal file
119
include/boost/range/detail/any_iterator_buffer.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
// 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
|
||||
|
||||
#undef BOOST_TEST_MESSAGE
|
||||
|
||||
#endif // include guard
|
258
include/boost/range/detail/any_iterator_interface.hpp
Normal file
258
include/boost/range/detail/any_iterator_interface.hpp
Normal file
@ -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
|
590
include/boost/range/detail/any_iterator_wrapper.hpp
Normal file
590
include/boost/range/detail/any_iterator_wrapper.hpp
Normal file
@ -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
|
28
include/boost/range/detail/begin.hpp
Executable file → Normal file
28
include/boost/range/detail/begin.hpp
Executable file → Normal 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'
|
||||
|
||||
|
||||
|
37
include/boost/range/detail/end.hpp
Executable file → Normal file
37
include/boost/range/detail/end.hpp
Executable file → Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user