mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-05-10 09:23:30 +00:00
[sprout.iterator] support for C++14 constexpr iterator operation
This commit is contained in:
parent
b192c5c214
commit
54b6a2be18
4 changed files with 69 additions and 66 deletions
|
@ -22,6 +22,27 @@ namespace sprout_adl {
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace iterator_detail {
|
namespace iterator_detail {
|
||||||
|
template<typename RandomAccessIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||||
|
cxx14_distance(RandomAccessIterator first, RandomAccessIterator last, std::random_access_iterator_tag*) {
|
||||||
|
return last - first;
|
||||||
|
}
|
||||||
|
template<typename InputIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||||
|
cxx14_distance(InputIterator first, InputIterator last, std::input_iterator_tag*) {
|
||||||
|
typename std::iterator_traits<InputIterator>::difference_type n = 0;
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
template<typename InputIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||||
|
cxx14_distance(InputIterator first, InputIterator last) {
|
||||||
|
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
||||||
|
return sprout::iterator_detail::cxx14_distance(first, last, category());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename RandomAccessIterator>
|
template<typename RandomAccessIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
sprout::is_constant_distance_iterator<RandomAccessIterator>::value,
|
sprout::is_constant_distance_iterator<RandomAccessIterator>::value,
|
||||||
|
@ -67,29 +88,29 @@ namespace sprout {
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename InputIterator>
|
|
||||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
|
||||||
iterator_distance(InputIterator first, InputIterator last, std::input_iterator_tag*) {
|
|
||||||
typedef sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> type;
|
|
||||||
return sprout::iterator_detail::iterator_distance_impl(type(first, 0), last, 1).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
std::is_literal_type<InputIterator>::value,
|
std::is_literal_type<InputIterator>::value,
|
||||||
typename std::iterator_traits<InputIterator>::difference_type
|
typename std::iterator_traits<InputIterator>::difference_type
|
||||||
>::type
|
>::type
|
||||||
iterator_distance(InputIterator first, InputIterator last) {
|
iterator_distance(InputIterator first, InputIterator last, std::input_iterator_tag*) {
|
||||||
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
typedef sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||||
return sprout::iterator_detail::iterator_distance(first, last, category());
|
return sprout::iterator_detail::iterator_distance_impl(type(first, 0), last, 1).second;
|
||||||
}
|
}
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
!std::is_literal_type<InputIterator>::value,
|
!std::is_literal_type<InputIterator>::value,
|
||||||
typename std::iterator_traits<InputIterator>::difference_type
|
typename std::iterator_traits<InputIterator>::difference_type
|
||||||
>::type
|
>::type
|
||||||
|
iterator_distance(InputIterator first, InputIterator last, std::input_iterator_tag*) {
|
||||||
|
return sprout::iterator_detail::cxx14_distance(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InputIterator>
|
||||||
|
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||||
iterator_distance(InputIterator first, InputIterator last) {
|
iterator_distance(InputIterator first, InputIterator last) {
|
||||||
return std::distance(first, last);
|
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
||||||
|
return sprout::iterator_detail::iterator_distance(first, last, category());
|
||||||
}
|
}
|
||||||
} // namespace iterator_detail
|
} // namespace iterator_detail
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
@ -110,9 +131,9 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
// effect:
|
// effect:
|
||||||
// ADL callable iterator_distance(first, last) -> iterator_distance(first, last)
|
// ADL callable iterator_distance(first, last) -> iterator_distance(first, last)
|
||||||
// otherwise, [first, last) is not LiteralType -> std::distance(first, last)
|
// otherwise, [first, last) is RandomAccessIterator && ConstantDistanceIterator -> last - first
|
||||||
// otherwise, [first, last) is RandomAccessIterator && not Pointer -> last - first
|
// otherwise, [first, last) is LiteralType -> linearly count: first to last
|
||||||
// otherwise -> linearly count: first to last
|
// otherwise -> cxx14_distance(first, last)
|
||||||
//
|
//
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/iterator/advance.hpp>
|
||||||
#include <sprout/iterator/next_fwd.hpp>
|
#include <sprout/iterator/next_fwd.hpp>
|
||||||
#include <sprout/iterator/prev_fwd.hpp>
|
#include <sprout/iterator/prev_fwd.hpp>
|
||||||
#include <sprout/adl/not_found.hpp>
|
#include <sprout/adl/not_found.hpp>
|
||||||
|
@ -24,36 +25,25 @@ namespace sprout_adl {
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace iterator_detail {
|
namespace iterator_detail {
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
InputIterator
|
inline SPROUT_CXX14_CONSTEXPR InputIterator
|
||||||
single_pass_next(InputIterator it, typename std::iterator_traits<InputIterator>::difference_type n = 1) {
|
cxx14_next(InputIterator it, typename std::iterator_traits<InputIterator>::difference_type n = 1) {
|
||||||
std::advance(it, n);
|
sprout::advance(it, n);
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RandomAccessIterator>
|
template<typename RandomAccessIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR RandomAccessIterator
|
||||||
std::is_literal_type<RandomAccessIterator>::value,
|
|
||||||
RandomAccessIterator
|
|
||||||
>::type
|
|
||||||
next_impl(RandomAccessIterator const& it, std::random_access_iterator_tag*) {
|
next_impl(RandomAccessIterator const& it, std::random_access_iterator_tag*) {
|
||||||
return it + 1;
|
return it + 1;
|
||||||
}
|
}
|
||||||
template<typename ForwardIterator>
|
|
||||||
inline SPROUT_CONSTEXPR ForwardIterator
|
|
||||||
next_impl(ForwardIterator const& it, std::forward_iterator_tag*) {
|
|
||||||
return std::next(it);
|
|
||||||
}
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR InputIterator
|
inline SPROUT_CONSTEXPR InputIterator
|
||||||
next_impl(InputIterator const& it, std::input_iterator_tag*) {
|
next_impl(InputIterator const& it, std::input_iterator_tag*) {
|
||||||
return sprout::iterator_detail::single_pass_next(it);
|
return sprout::iterator_detail::cxx14_next(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RandomAccessIterator>
|
template<typename RandomAccessIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR RandomAccessIterator
|
||||||
std::is_literal_type<RandomAccessIterator>::value,
|
|
||||||
RandomAccessIterator
|
|
||||||
>::type
|
|
||||||
next_impl(
|
next_impl(
|
||||||
RandomAccessIterator const& it, typename std::iterator_traits<RandomAccessIterator>::difference_type n,
|
RandomAccessIterator const& it, typename std::iterator_traits<RandomAccessIterator>::difference_type n,
|
||||||
std::random_access_iterator_tag*
|
std::random_access_iterator_tag*
|
||||||
|
@ -121,18 +111,6 @@ namespace sprout {
|
||||||
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
||||||
return sprout::iterator_detail::next_impl_1(it, n, category());
|
return sprout::iterator_detail::next_impl_1(it, n, category());
|
||||||
}
|
}
|
||||||
template<typename ForwardIterator>
|
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
|
||||||
!std::is_literal_type<ForwardIterator>::value,
|
|
||||||
ForwardIterator
|
|
||||||
>::type
|
|
||||||
next_impl(
|
|
||||||
ForwardIterator const& it, typename std::iterator_traits<ForwardIterator>::difference_type n,
|
|
||||||
std::forward_iterator_tag*
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return std::next(it, n);
|
|
||||||
}
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
!std::is_literal_type<InputIterator>::value,
|
!std::is_literal_type<InputIterator>::value,
|
||||||
|
@ -143,7 +121,7 @@ namespace sprout {
|
||||||
std::input_iterator_tag*
|
std::input_iterator_tag*
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return sprout::iterator_detail::single_pass_next(it, n);
|
return sprout::iterator_detail::cxx14_next(it, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
|
@ -184,9 +162,8 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
// effect:
|
// effect:
|
||||||
// ADL callable iterator_next(it) -> iterator_next(it)
|
// ADL callable iterator_next(it) -> iterator_next(it)
|
||||||
// it is RandomAccessIterator && LiteralType -> it + 1
|
// it is RandomAccessIterator -> it + 1
|
||||||
// it is ForwardIterator -> std::next(it)
|
// otherwise -> cxx14_next(it)
|
||||||
// otherwise -> single_pass_next(it)
|
|
||||||
//
|
//
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR InputIterator
|
inline SPROUT_CONSTEXPR InputIterator
|
||||||
|
@ -196,11 +173,10 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
// effect:
|
// effect:
|
||||||
// ADL callable iterator_next(it, n) -> iterator_next(it, n)
|
// ADL callable iterator_next(it, n) -> iterator_next(it, n)
|
||||||
// it is RandomAccessIterator && LiteralType -> it + n
|
// it is RandomAccessIterator -> it + n
|
||||||
// it is LiteralType && n >= 0 -> sprout::next(it)...
|
// it is LiteralType && n >= 0 -> sprout::next(it)...
|
||||||
// it is LiteralType && n < 0 -> sprout::prev(it)...
|
// it is LiteralType && n < 0 -> sprout::prev(it)...
|
||||||
// it is ForwardIterator -> std::next(it, n)
|
// otherwise -> cxx14_next(it, n)
|
||||||
// otherwise -> single_pass_next(it, n)
|
|
||||||
//
|
//
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
inline SPROUT_CONSTEXPR InputIterator
|
inline SPROUT_CONSTEXPR InputIterator
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/iterator/advance.hpp>
|
||||||
#include <sprout/iterator/next_fwd.hpp>
|
#include <sprout/iterator/next_fwd.hpp>
|
||||||
#include <sprout/iterator/prev_fwd.hpp>
|
#include <sprout/iterator/prev_fwd.hpp>
|
||||||
#include <sprout/adl/not_found.hpp>
|
#include <sprout/adl/not_found.hpp>
|
||||||
|
@ -21,25 +22,26 @@ namespace sprout_adl {
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace iterator_detail {
|
namespace iterator_detail {
|
||||||
|
template<typename InputIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR InputIterator
|
||||||
|
cxx14_prev(InputIterator it, typename std::iterator_traits<InputIterator>::difference_type n = 1) {
|
||||||
|
sprout::advance(it, -n);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename RandomAccessIterator>
|
template<typename RandomAccessIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR RandomAccessIterator
|
||||||
std::is_literal_type<RandomAccessIterator>::value,
|
|
||||||
RandomAccessIterator
|
|
||||||
>::type
|
|
||||||
prev_impl(RandomAccessIterator const& it, std::random_access_iterator_tag*) {
|
prev_impl(RandomAccessIterator const& it, std::random_access_iterator_tag*) {
|
||||||
return it - 1;
|
return it - 1;
|
||||||
}
|
}
|
||||||
template<typename BidirectionalIterator>
|
template<typename BidirectionalIterator>
|
||||||
inline SPROUT_CONSTEXPR BidirectionalIterator
|
inline SPROUT_CONSTEXPR BidirectionalIterator
|
||||||
prev_impl(BidirectionalIterator const& it, std::bidirectional_iterator_tag*) {
|
prev_impl(BidirectionalIterator const& it, std::bidirectional_iterator_tag*) {
|
||||||
return std::prev(it);
|
return sprout::iterator_detail::cxx14_prev(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RandomAccessIterator>
|
template<typename RandomAccessIterator>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR RandomAccessIterator
|
||||||
std::is_literal_type<RandomAccessIterator>::value,
|
|
||||||
RandomAccessIterator
|
|
||||||
>::type
|
|
||||||
prev_impl(
|
prev_impl(
|
||||||
RandomAccessIterator const& it, typename std::iterator_traits<RandomAccessIterator>::difference_type n,
|
RandomAccessIterator const& it, typename std::iterator_traits<RandomAccessIterator>::difference_type n,
|
||||||
std::random_access_iterator_tag*
|
std::random_access_iterator_tag*
|
||||||
|
@ -94,7 +96,7 @@ namespace sprout {
|
||||||
std::bidirectional_iterator_tag*
|
std::bidirectional_iterator_tag*
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return std::prev(it, n);
|
return sprout::iterator_detail::cxx14_prev(it, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BidirectionalIterator>
|
template<typename BidirectionalIterator>
|
||||||
|
@ -135,8 +137,8 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
// effect:
|
// effect:
|
||||||
// ADL callable iterator_prev(it) -> iterator_prev(it)
|
// ADL callable iterator_prev(it) -> iterator_prev(it)
|
||||||
// it is RandomAccessIterator && LiteralType -> it - 1
|
// it is RandomAccessIterator -> it - 1
|
||||||
// otherwise -> std::prev(it)
|
// otherwise -> cxx14_prev(it)
|
||||||
//
|
//
|
||||||
template<typename BidirectionalIterator>
|
template<typename BidirectionalIterator>
|
||||||
inline SPROUT_CONSTEXPR BidirectionalIterator
|
inline SPROUT_CONSTEXPR BidirectionalIterator
|
||||||
|
@ -146,9 +148,10 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
// effect:
|
// effect:
|
||||||
// ADL callable iterator_prev(it, n) -> iterator_prev(it, n)
|
// ADL callable iterator_prev(it, n) -> iterator_prev(it, n)
|
||||||
// it is RandomAccessIterator && LiteralType -> it - n
|
// it is RandomAccessIterator -> it - n
|
||||||
// it is LiteralType -> sprout::prev(it)... || sprout::next(it)...
|
// it is LiteralType && n >= 0 -> sprout::prev(it)...
|
||||||
// otherwise -> std::prev(it, n)
|
// it is LiteralType && n < 0 -> sprout::next(it)...
|
||||||
|
// otherwise -> cxx14_prev(it, n)
|
||||||
//
|
//
|
||||||
template<typename BidirectionalIterator>
|
template<typename BidirectionalIterator>
|
||||||
inline SPROUT_CONSTEXPR BidirectionalIterator
|
inline SPROUT_CONSTEXPR BidirectionalIterator
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
|
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
|
||||||
//
|
//
|
||||||
// is_constant_distance_iterator
|
// is_constant_distance_iterator
|
||||||
//
|
//
|
||||||
|
@ -21,7 +20,11 @@ namespace sprout {
|
||||||
struct is_constant_distance_iterator
|
struct is_constant_distance_iterator
|
||||||
: public std::integral_constant<
|
: public std::integral_constant<
|
||||||
bool,
|
bool,
|
||||||
|
#ifdef SPROUT_NO_CXX14_CONSTEXPR
|
||||||
sprout::is_random_access_iterator<MaybeIterator>::value && !std::is_pointer<MaybeIterator>::value
|
sprout::is_random_access_iterator<MaybeIterator>::value && !std::is_pointer<MaybeIterator>::value
|
||||||
|
#else // #ifdef SPROUT_NO_CXX14_CONSTEXPR
|
||||||
|
sprout::is_random_access_iterator<MaybeIterator>::value
|
||||||
|
#endif // #ifdef SPROUT_NO_CXX14_CONSTEXPR
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
Loading…
Add table
Reference in a new issue