mirror of
https://github.com/boostorg/range.git
synced 2025-07-30 12:57:28 +02:00
Merge pull request #28 from ericniebler/develop
make range_iterator, range_difference, and range_size SFINAE-friendly, r...
This commit is contained in:
@ -15,20 +15,37 @@
|
|||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
#include <boost/range/config.hpp>
|
#include <boost/range/config.hpp>
|
||||||
#include <boost/range/iterator.hpp>
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/range/has_range_iterator.hpp>
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
template< class T, class Enabler=void >
|
||||||
|
struct range_difference
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct range_difference<
|
||||||
|
T,
|
||||||
|
BOOST_DEDUCED_TYPENAME ::boost::enable_if_c<
|
||||||
|
has_type<range_iterator<T> >::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
: iterator_difference<
|
||||||
|
BOOST_DEDUCED_TYPENAME range_iterator<T>::type
|
||||||
|
>
|
||||||
|
{ };
|
||||||
|
}
|
||||||
|
|
||||||
template< class T >
|
template< class T >
|
||||||
struct range_difference
|
struct range_difference
|
||||||
: iterator_difference<
|
: range_detail::range_difference<BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
|
||||||
BOOST_DEDUCED_TYPENAME range_iterator<
|
|
||||||
BOOST_DEDUCED_TYPENAME remove_reference<T>::type
|
|
||||||
>::type
|
|
||||||
>
|
|
||||||
{ };
|
{ };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,31 +46,29 @@ namespace boost
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template< typename C, typename Enabler=void >
|
template< typename C, typename Enabler=void >
|
||||||
struct range_iterator
|
struct range_iterator
|
||||||
{
|
{
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
|
||||||
|
|
||||||
typedef BOOST_RANGE_DEDUCED_TYPENAME
|
typedef BOOST_RANGE_DEDUCED_TYPENAME
|
||||||
range_detail_vc7_1::range_iterator<C>::type type;
|
range_detail_vc7_1::range_iterator<C>::type type;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef typename remove_reference<C>::type param_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename mpl::eval_if_c<
|
|
||||||
is_const<param_t>::value,
|
|
||||||
range_const_iterator<typename remove_const<param_t>::type>,
|
|
||||||
range_mutable_iterator<param_t>
|
|
||||||
>::type type;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template< typename C, typename Enabler=void >
|
||||||
|
struct range_iterator
|
||||||
|
: mpl::if_c<
|
||||||
|
is_const<typename remove_reference<C>::type>::value,
|
||||||
|
range_const_iterator<typename remove_const<typename remove_reference<C>::type>::type>,
|
||||||
|
range_mutable_iterator<typename remove_reference<C>::type>
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <boost/range/config.hpp>
|
#include <boost/range/config.hpp>
|
||||||
#include <boost/range/difference_type.hpp>
|
#include <boost/range/difference_type.hpp>
|
||||||
#include <boost/range/concepts.hpp>
|
#include <boost/range/concepts.hpp>
|
||||||
|
#include <boost/range/has_range_iterator.hpp>
|
||||||
|
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
#include <boost/type_traits/make_unsigned.hpp>
|
#include <boost/type_traits/make_unsigned.hpp>
|
||||||
@ -51,7 +52,7 @@ namespace boost
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename C, typename Enabler=void>
|
template<typename C, typename Enabler=void>
|
||||||
struct range_size
|
struct range_size_
|
||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME make_unsigned<
|
typedef BOOST_DEDUCED_TYPENAME make_unsigned<
|
||||||
BOOST_DEDUCED_TYPENAME range_difference<C>::type
|
BOOST_DEDUCED_TYPENAME range_difference<C>::type
|
||||||
@ -59,7 +60,7 @@ namespace boost
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename C>
|
template<typename C>
|
||||||
struct range_size<
|
struct range_size_<
|
||||||
C,
|
C,
|
||||||
BOOST_DEDUCED_TYPENAME ::boost::enable_if<has_size_type<C>, void>::type
|
BOOST_DEDUCED_TYPENAME ::boost::enable_if<has_size_type<C>, void>::type
|
||||||
>
|
>
|
||||||
@ -67,29 +68,38 @@ namespace boost
|
|||||||
typedef BOOST_DEDUCED_TYPENAME C::size_type type;
|
typedef BOOST_DEDUCED_TYPENAME C::size_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
template<typename C, typename Enabler=void>
|
||||||
|
struct range_size
|
||||||
|
{ };
|
||||||
|
|
||||||
template< class T >
|
template<typename C>
|
||||||
struct range_size :
|
struct range_size<
|
||||||
detail::range_size<T>
|
C,
|
||||||
{
|
BOOST_DEDUCED_TYPENAME ::boost::enable_if_c<
|
||||||
|
range_detail::has_type< range_iterator<C> >::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
: range_size_<C>
|
||||||
|
{
|
||||||
// Very strange things happen on some compilers that have the range concept
|
// Very strange things happen on some compilers that have the range concept
|
||||||
// asserts disabled. This preprocessor condition is clearly redundant on a
|
// asserts disabled. This preprocessor condition is clearly redundant on a
|
||||||
// working compiler but is vital for at least some compilers such as clang 4.2
|
// working compiler but is vital for at least some compilers such as clang 4.2
|
||||||
// but only on the Mac!
|
// but only on the Mac!
|
||||||
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
|
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<T>));
|
BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<C>));
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template< class T >
|
template< class T >
|
||||||
struct range_size<const T >
|
struct range_size :
|
||||||
: detail::range_size<T>
|
detail::range_size<T>
|
||||||
{
|
{ };
|
||||||
#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
|
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<T>));
|
template< class T >
|
||||||
#endif
|
struct range_size<const T > :
|
||||||
};
|
detail::range_size<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user