mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-08-03 12:49:50 +00:00
add subscript_at function
This commit is contained in:
parent
8278a2642c
commit
0080332dd5
12 changed files with 341 additions and 54 deletions
|
@ -35,6 +35,7 @@ namespace sprout_adl {
|
|||
sprout::not_found_via_adl range_empty(...);
|
||||
sprout::not_found_via_adl range_front(...);
|
||||
sprout::not_found_via_adl range_back(...);
|
||||
sprout::not_found_via_adl range_subscript_at(...);
|
||||
sprout::not_found_via_adl range_at(...);
|
||||
sprout::not_found_via_adl range_nth(...);
|
||||
sprout::not_found_via_adl range_index_of(...);
|
||||
|
@ -585,6 +586,89 @@ namespace sprout {
|
|||
return *sprout::next(sprout::begin(cont), sprout::size(cont) - 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct has_mem_subscript_test {
|
||||
public:
|
||||
template<
|
||||
typename U = T,
|
||||
typename = typename sprout::identity<decltype(std::declval<U>()[std::declval<typename sprout::container_traits<U>::size_type>()])>::type
|
||||
>
|
||||
static sprout::true_type test(int);
|
||||
static sprout::false_type test(...);
|
||||
};
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1900)
|
||||
template<typename T, typename Base_ = typename sprout::identity<decltype(sprout::detail::has_mem_subscript_test<T>::test(0))>::type>
|
||||
struct has_mem_subscript
|
||||
: public Base_
|
||||
{};
|
||||
#else
|
||||
template<typename T>
|
||||
struct has_mem_subscript
|
||||
: public sprout::identity<decltype(sprout::detail::has_mem_subscript_test<T>::test(0))>::type
|
||||
{};
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct is_substitutable_const_subscript_at
|
||||
: public sprout::bool_constant<
|
||||
sprout::is_const_cast_convertible<
|
||||
typename sprout::container_traits<T const>::reference,
|
||||
typename sprout::container_traits<T>::reference
|
||||
>::value
|
||||
&& (
|
||||
sprout::detail::has_mem_subscript<T const>::value
|
||||
|| sprout::detail::has_mem_begin<T const>::value
|
||||
|| sprout::detail::has_adl_begin_without_sprout<T const&>::value
|
||||
)
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::detail::is_substitutable_const_subscript_at<Container>::value,
|
||||
typename sprout::container_traits<Container>::reference
|
||||
>::type
|
||||
range_subscript_at_impl(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
typedef typename sprout::container_traits<Container>::reference type;
|
||||
return const_cast<type>(sprout::subscript_at(sprout::as_const(cont), i));
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::is_substitutable_const_subscript_at<Container>::value
|
||||
&& sprout::detail::has_mem_subscript<Container>::value
|
||||
,
|
||||
typename sprout::container_traits<Container>::reference
|
||||
>::type
|
||||
range_subscript_at_impl(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
return cont[i];
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::is_substitutable_const_subscript_at<Container>::value
|
||||
&& !sprout::detail::has_mem_subscript<Container>::value
|
||||
,
|
||||
typename sprout::container_traits<Container>::reference
|
||||
>::type
|
||||
range_subscript_at_impl(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
return *sprout::next(sprout::begin(cont), i);
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::detail::has_mem_subscript<Container const>::value,
|
||||
typename sprout::container_traits<Container const>::reference
|
||||
>::type
|
||||
range_subscript_at_impl(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return cont[i];
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::has_mem_subscript<Container const>::value,
|
||||
typename sprout::container_traits<Container const>::reference
|
||||
>::type
|
||||
range_subscript_at_impl(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return *sprout::next(sprout::begin(cont), i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct has_mem_at_test {
|
||||
public:
|
||||
|
@ -616,6 +700,7 @@ namespace sprout {
|
|||
>::value
|
||||
&& (
|
||||
sprout::detail::has_mem_at<T const>::value
|
||||
|| sprout::detail::has_mem_subscript<T const>::value
|
||||
|| sprout::detail::has_mem_begin<T const>::value
|
||||
|| sprout::detail::has_adl_begin_without_sprout<T const&>::value
|
||||
)
|
||||
|
@ -645,11 +730,23 @@ namespace sprout {
|
|||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::is_substitutable_const_at<Container>::value
|
||||
&& !sprout::detail::has_mem_at<Container>::value
|
||||
&& sprout::detail::has_mem_subscript<Container>::value
|
||||
,
|
||||
typename sprout::container_traits<Container>::reference
|
||||
>::type
|
||||
range_at_impl(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
return *sprout::next(sprout::begin(cont), i);
|
||||
return cont[sprout::range_index_check(cont, i)];
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::is_substitutable_const_at<Container>::value
|
||||
&& !sprout::detail::has_mem_at<Container>::value
|
||||
&& !sprout::detail::has_mem_subscript<Container>::value
|
||||
,
|
||||
typename sprout::container_traits<Container>::reference
|
||||
>::type
|
||||
range_at_impl(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
return *sprout::next(sprout::begin(cont), sprout::range_index_check(cont, i));
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
|
@ -661,11 +758,23 @@ namespace sprout {
|
|||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::has_mem_at<Container const>::value,
|
||||
!sprout::detail::has_mem_at<Container const>::value
|
||||
&& sprout::detail::has_mem_subscript<Container>::value
|
||||
,
|
||||
typename sprout::container_traits<Container const>::reference
|
||||
>::type
|
||||
range_at_impl(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return *sprout::next(sprout::begin(cont), i);
|
||||
return cont[sprout::range_index_check(cont, i)];
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!sprout::detail::has_mem_at<Container const>::value
|
||||
&& !sprout::detail::has_mem_subscript<Container>::value
|
||||
,
|
||||
typename sprout::container_traits<Container const>::reference
|
||||
>::type
|
||||
range_at_impl(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return *sprout::next(sprout::begin(cont), sprout::range_index_check(cont, i));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -949,6 +1058,17 @@ namespace sprout_container_range_detail {
|
|||
return sprout::detail::range_back_impl(cont);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||
range_subscript_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
return sprout::detail::range_subscript_at_impl(cont, i);
|
||||
}
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||
range_subscript_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return sprout::detail::range_subscript_at_impl(cont, i);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||
range_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
|
@ -1066,6 +1186,18 @@ namespace sprout {
|
|||
return range_back(cont);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||
range_subscript_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
using sprout_container_range_detail::range_subscript_at;
|
||||
using sprout_adl::range_subscript_at;
|
||||
return range_subscript_at(cont, i);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||
range_subscript_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
using sprout_container_range_detail::range_subscript_at;
|
||||
using sprout_adl::range_subscript_at;
|
||||
return range_subscript_at(cont, i);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||
range_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||
using sprout_container_range_detail::range_at;
|
||||
using sprout_adl::range_at;
|
||||
|
@ -1149,6 +1281,10 @@ namespace sprout {
|
|||
return sprout::container_range_traits<Container>::range_back(cont);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||
range_subscript_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return sprout::container_range_traits<Container>::range_subscript_at(cont, i);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||
range_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||
return sprout::container_range_traits<Container>::range_at(cont, i);
|
||||
}
|
||||
|
@ -1231,6 +1367,14 @@ namespace sprout {
|
|||
return arr[N - 1];
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T[N]>::reference
|
||||
range_subscript_at(T (& arr)[N], typename sprout::container_traits<T[N]>::size_type i) {
|
||||
return arr[i];
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::reference
|
||||
range_subscript_at(T const (& arr)[N], typename sprout::container_traits<T const[N]>::size_type i) {
|
||||
return arr[i];
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T[N]>::reference
|
||||
range_at(T (& arr)[N], typename sprout::container_traits<T[N]>::size_type i) {
|
||||
return arr[i];
|
||||
}
|
||||
|
@ -1301,6 +1445,10 @@ namespace sprout {
|
|||
return sprout::container_range_traits<T[N]>::range_back(arr);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::reference
|
||||
range_subscript_at(T const (& arr)[N], typename sprout::container_traits<T const[N]>::size_type i) {
|
||||
return sprout::container_range_traits<T[N]>::range_subscript_at(arr, i);
|
||||
}
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::reference
|
||||
range_at(T const (& arr)[N], typename sprout::container_traits<T const[N]>::size_type i) {
|
||||
return sprout::container_range_traits<T[N]>::range_at(arr, i);
|
||||
}
|
||||
|
@ -1325,8 +1473,11 @@ namespace sprout {
|
|||
#include <sprout/container/size.hpp>
|
||||
#include <sprout/container/front.hpp>
|
||||
#include <sprout/container/back.hpp>
|
||||
#include <sprout/container/subscript_at.hpp>
|
||||
#include <sprout/container/at.hpp>
|
||||
#include <sprout/container/nth.hpp>
|
||||
#include <sprout/container/index_of.hpp>
|
||||
#include <sprout/container/data.hpp>
|
||||
#include <sprout/container/range_index_check.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_CONTAINER_CONTAINER_RANGE_TRAITS_HPP
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue