mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add subscript_at function
This commit is contained in:
parent
8278a2642c
commit
0080332dd5
12 changed files with 341 additions and 54 deletions
|
@ -8,7 +8,7 @@
|
||||||
#ifndef SPROUT_ADAPT_BOOST_ARRAY_HPP
|
#ifndef SPROUT_ADAPT_BOOST_ARRAY_HPP
|
||||||
#define SPROUT_ADAPT_BOOST_ARRAY_HPP
|
#define SPROUT_ADAPT_BOOST_ARRAY_HPP
|
||||||
|
|
||||||
#include <array>
|
#include <boost/array.hpp>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/container/boost/array.hpp>
|
#include <sprout/container/boost/array.hpp>
|
||||||
#include <sprout/functional/hash/boost/array.hpp>
|
#include <sprout/functional/hash/boost/array.hpp>
|
||||||
|
|
|
@ -26,12 +26,14 @@ namespace sprout {
|
||||||
// otherwise, Container is not const
|
// otherwise, Container is not const
|
||||||
// && sprout::is_const_cast_convertible<const_reference, reference>
|
// && sprout::is_const_cast_convertible<const_reference, reference>
|
||||||
// && (callable sprout::as_const(cont).at(i)
|
// && (callable sprout::as_const(cont).at(i)
|
||||||
|
// || callable sprout::as_const(cont)[i]
|
||||||
// || callable sprout::as_const(cont).begin()
|
// || callable sprout::as_const(cont).begin()
|
||||||
// || ADL(without sprout) callable begin(sprout::as_const(cont))
|
// || ADL(without sprout) callable begin(sprout::as_const(cont))
|
||||||
// )
|
// )
|
||||||
// -> const_cast<reference>(sprout::at(sprout::as_const(cont), i))
|
// -> const_cast<reference>(sprout::at(sprout::as_const(cont), i))
|
||||||
// otherwise, callable cont.at(i) -> cont.at(i)
|
// otherwise, callable cont.at(i) -> cont.at(i)
|
||||||
// otherwise -> *sprout::next(sprout::begin(cont), i)
|
// otherwise, callable cont[i] -> cont[sprout::range_index_check(cont, i)]
|
||||||
|
// otherwise -> *sprout::next(sprout::begin(cont), sprout::range_index_check(cont, i))
|
||||||
//
|
//
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/container/traits.hpp>
|
#include <sprout/container/traits.hpp>
|
||||||
|
#include <sprout/container/range_index_check.hpp>
|
||||||
#include <sprout/iterator/index_iterator.hpp>
|
#include <sprout/iterator/index_iterator.hpp>
|
||||||
#include <sprout/utility/forward.hpp>
|
#include <sprout/utility/forward.hpp>
|
||||||
#include <sprout/functional/transparent.hpp>
|
#include <sprout/functional/transparent.hpp>
|
||||||
|
@ -101,13 +102,21 @@ namespace sprout {
|
||||||
return cont.elems[N - 1];
|
return cont.elems[N - 1];
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> >::reference
|
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> >::reference
|
||||||
range_at(boost::array<T, N>& cont, typename sprout::container_traits<boost::array<T, N> >::size_type i) {
|
range_subscript_at(boost::array<T, N>& cont, typename sprout::container_traits<boost::array<T, N> >::size_type i) {
|
||||||
return cont.elems[i];
|
return cont.elems[i];
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> const>::reference
|
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> const>::reference
|
||||||
range_at(boost::array<T, N> const& cont, typename sprout::container_traits<boost::array<T, N> const>::size_type i) {
|
range_subscript_at(boost::array<T, N> const& cont, typename sprout::container_traits<boost::array<T, N> const>::size_type i) {
|
||||||
return cont.elems[i];
|
return cont.elems[i];
|
||||||
}
|
}
|
||||||
|
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> >::reference
|
||||||
|
range_at(boost::array<T, N>& cont, typename sprout::container_traits<boost::array<T, N> >::size_type i) {
|
||||||
|
return cont.elems[sprout::range_index_check(cont, i)];
|
||||||
|
}
|
||||||
|
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> const>::reference
|
||||||
|
range_at(boost::array<T, N> const& cont, typename sprout::container_traits<boost::array<T, N> const>::size_type i) {
|
||||||
|
return cont.elems[sprout::range_index_check(cont, i)];
|
||||||
|
}
|
||||||
// data access:
|
// data access:
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> >::pointer
|
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> >::pointer
|
||||||
range_data(boost::array<T, N>& cont) {
|
range_data(boost::array<T, N>& cont) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace sprout_adl {
|
||||||
sprout::not_found_via_adl range_empty(...);
|
sprout::not_found_via_adl range_empty(...);
|
||||||
sprout::not_found_via_adl range_front(...);
|
sprout::not_found_via_adl range_front(...);
|
||||||
sprout::not_found_via_adl range_back(...);
|
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_at(...);
|
||||||
sprout::not_found_via_adl range_nth(...);
|
sprout::not_found_via_adl range_nth(...);
|
||||||
sprout::not_found_via_adl range_index_of(...);
|
sprout::not_found_via_adl range_index_of(...);
|
||||||
|
@ -585,6 +586,89 @@ namespace sprout {
|
||||||
return *sprout::next(sprout::begin(cont), sprout::size(cont) - 1);
|
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>
|
template<typename T>
|
||||||
struct has_mem_at_test {
|
struct has_mem_at_test {
|
||||||
public:
|
public:
|
||||||
|
@ -616,6 +700,7 @@ namespace sprout {
|
||||||
>::value
|
>::value
|
||||||
&& (
|
&& (
|
||||||
sprout::detail::has_mem_at<T const>::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_mem_begin<T const>::value
|
||||||
|| sprout::detail::has_adl_begin_without_sprout<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<
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
!sprout::detail::is_substitutable_const_at<Container>::value
|
!sprout::detail::is_substitutable_const_at<Container>::value
|
||||||
&& !sprout::detail::has_mem_at<Container>::value
|
&& !sprout::detail::has_mem_at<Container>::value
|
||||||
|
&& sprout::detail::has_mem_subscript<Container>::value
|
||||||
,
|
,
|
||||||
typename sprout::container_traits<Container>::reference
|
typename sprout::container_traits<Container>::reference
|
||||||
>::type
|
>::type
|
||||||
range_at_impl(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
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>
|
template<typename Container>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
@ -661,11 +758,23 @@ namespace sprout {
|
||||||
}
|
}
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
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
|
typename sprout::container_traits<Container const>::reference
|
||||||
>::type
|
>::type
|
||||||
range_at_impl(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
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>
|
template<typename T>
|
||||||
|
@ -949,6 +1058,17 @@ namespace sprout_container_range_detail {
|
||||||
return sprout::detail::range_back_impl(cont);
|
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>
|
template<typename Container>
|
||||||
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||||
range_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
range_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||||
|
@ -1066,6 +1186,18 @@ namespace sprout {
|
||||||
return range_back(cont);
|
return range_back(cont);
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
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) {
|
range_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||||
using sprout_container_range_detail::range_at;
|
using sprout_container_range_detail::range_at;
|
||||||
using sprout_adl::range_at;
|
using sprout_adl::range_at;
|
||||||
|
@ -1149,6 +1281,10 @@ namespace sprout {
|
||||||
return sprout::container_range_traits<Container>::range_back(cont);
|
return sprout::container_range_traits<Container>::range_back(cont);
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
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) {
|
range_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||||
return sprout::container_range_traits<Container>::range_at(cont, i);
|
return sprout::container_range_traits<Container>::range_at(cont, i);
|
||||||
}
|
}
|
||||||
|
@ -1231,6 +1367,14 @@ namespace sprout {
|
||||||
return arr[N - 1];
|
return arr[N - 1];
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T[N]>::reference
|
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) {
|
range_at(T (& arr)[N], typename sprout::container_traits<T[N]>::size_type i) {
|
||||||
return arr[i];
|
return arr[i];
|
||||||
}
|
}
|
||||||
|
@ -1301,6 +1445,10 @@ namespace sprout {
|
||||||
return sprout::container_range_traits<T[N]>::range_back(arr);
|
return sprout::container_range_traits<T[N]>::range_back(arr);
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::reference
|
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) {
|
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);
|
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/size.hpp>
|
||||||
#include <sprout/container/front.hpp>
|
#include <sprout/container/front.hpp>
|
||||||
#include <sprout/container/back.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/nth.hpp>
|
||||||
#include <sprout/container/index_of.hpp>
|
#include <sprout/container/index_of.hpp>
|
||||||
#include <sprout/container/data.hpp>
|
#include <sprout/container/data.hpp>
|
||||||
|
#include <sprout/container/range_index_check.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_CONTAINER_CONTAINER_RANGE_TRAITS_HPP
|
#endif // #ifndef SPROUT_CONTAINER_CONTAINER_RANGE_TRAITS_HPP
|
||||||
|
|
|
@ -14,6 +14,5 @@
|
||||||
#include <sprout/container/construct_functions.hpp>
|
#include <sprout/container/construct_functions.hpp>
|
||||||
#include <sprout/container/fitness_functions.hpp>
|
#include <sprout/container/fitness_functions.hpp>
|
||||||
#include <sprout/container/sub_functions.hpp>
|
#include <sprout/container/sub_functions.hpp>
|
||||||
#include <sprout/container/shrink_to_fit.hpp>
|
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_CONTAINER_FUNCTIONS_HPP
|
#endif // #ifndef SPROUT_CONTAINER_FUNCTIONS_HPP
|
||||||
|
|
|
@ -20,5 +20,7 @@
|
||||||
#include <sprout/container/nth.hpp>
|
#include <sprout/container/nth.hpp>
|
||||||
#include <sprout/container/index_of.hpp>
|
#include <sprout/container/index_of.hpp>
|
||||||
#include <sprout/container/data.hpp>
|
#include <sprout/container/data.hpp>
|
||||||
|
#include <sprout/container/range_index_check.hpp>
|
||||||
|
#include <sprout/container/shrink_to_fit.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_CONTAINER_RANGE_FUNCTIONS_HPP
|
#endif // #ifndef SPROUT_CONTAINER_RANGE_FUNCTIONS_HPP
|
||||||
|
|
|
@ -66,6 +66,16 @@ namespace sprout {
|
||||||
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||||
back(Container const& cont);
|
back(Container const& cont);
|
||||||
|
|
||||||
|
//
|
||||||
|
// subscript_at
|
||||||
|
//
|
||||||
|
template<typename Container>
|
||||||
|
SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||||
|
subscript_at(Container& cont, typename sprout::container_traits<Container>::size_type i);
|
||||||
|
template<typename Container>
|
||||||
|
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||||
|
subscript_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i);
|
||||||
|
|
||||||
//
|
//
|
||||||
// at
|
// at
|
||||||
//
|
//
|
||||||
|
@ -105,8 +115,21 @@ namespace sprout {
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::pointer
|
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::pointer
|
||||||
data(Container const& cont);
|
data(Container const& cont);
|
||||||
} // namespace sprout
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// range_index_check
|
||||||
|
//
|
||||||
|
template<typename Container>
|
||||||
|
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::size_type
|
||||||
|
range_index_check(Container const& cont, typename sprout::container_traits<Container const>::size_type i);
|
||||||
|
|
||||||
|
//
|
||||||
|
// shrink_to_fit
|
||||||
|
//
|
||||||
|
template<typename Container>
|
||||||
|
SPROUT_CXX14_CONSTEXPR void
|
||||||
|
shrink_to_fit(Container&& cont);
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
#include <sprout/container/size.hpp>
|
#include <sprout/container/size.hpp>
|
||||||
#include <sprout/container/empty.hpp>
|
#include <sprout/container/empty.hpp>
|
||||||
|
|
31
sprout/container/range_index_check.hpp
Normal file
31
sprout/container/range_index_check.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2011-2016 Bolero MURAKAMI
|
||||||
|
https://github.com/bolero-MURAKAMI/Sprout
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
=============================================================================*/
|
||||||
|
#ifndef SPROUT_CONTAINER_RANGE_INDEX_CHECK_HPP
|
||||||
|
#define SPROUT_CONTAINER_RANGE_INDEX_CHECK_HPP
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/container/range_functions_fwd.hpp>
|
||||||
|
#include <sprout/container/container_traits.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
//
|
||||||
|
// range_index_check
|
||||||
|
//
|
||||||
|
template<typename Container>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::size_type
|
||||||
|
range_index_check(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||||
|
return i >= sprout::size(cont) ? throw std::out_of_range("range_index_check: index out of range")
|
||||||
|
: i
|
||||||
|
;
|
||||||
|
}
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#include <sprout/container/size.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_CONTAINER_RANGE_INDEX_CHECK_HPP
|
|
@ -15,6 +15,7 @@
|
||||||
# include <sprout/workaround/std/cstddef.hpp>
|
# include <sprout/workaround/std/cstddef.hpp>
|
||||||
# include <sprout/container/traits.hpp>
|
# include <sprout/container/traits.hpp>
|
||||||
# include <sprout/iterator/index_iterator.hpp>
|
# include <sprout/iterator/index_iterator.hpp>
|
||||||
|
# include <sprout/detail/functional/const_subscript.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
||||||
|
@ -27,8 +28,8 @@ namespace sprout {
|
||||||
: public sprout::detail::container_traits_default<sscrisk::cel::array<T, N> >
|
: public sprout::detail::container_traits_default<sscrisk::cel::array<T, N> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef sprout::index_iterator<sscrisk::cel::array<T, N>&, true> iterator;
|
typedef sprout::index_iterator<sscrisk::cel::array<T, N>&, true, sprout::detail::const_subscript<> > iterator;
|
||||||
typedef sprout::index_iterator<sscrisk::cel::array<T, N> const&, true> const_iterator;
|
typedef sprout::index_iterator<sscrisk::cel::array<T, N> const&, true, sprout::detail::const_subscript<> > const_iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -18,27 +18,9 @@
|
||||||
#include <sprout/utility/forward.hpp>
|
#include <sprout/utility/forward.hpp>
|
||||||
#include <sprout/utility/as_const.hpp>
|
#include <sprout/utility/as_const.hpp>
|
||||||
#include <sprout/memory/addressof.hpp>
|
#include <sprout/memory/addressof.hpp>
|
||||||
#include <sprout/functional/transparent.hpp>
|
#include <sprout/detail/functional/const_subscript.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace detail {
|
|
||||||
template<typename T = void>
|
|
||||||
struct const_subscript;
|
|
||||||
template<>
|
|
||||||
struct const_subscript<void>
|
|
||||||
: public sprout::transparent<>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template<typename T, typename U>
|
|
||||||
SPROUT_CONSTEXPR decltype(std::declval<T>()[std::declval<U>()])
|
|
||||||
operator()(T&& x, U&& y)
|
|
||||||
const SPROUT_NOEXCEPT_IF_EXPR(const_cast<decltype(std::declval<T>()[std::declval<U>()])>(sprout::as_const(std::declval<T>())[std::declval<U>()]))
|
|
||||||
{
|
|
||||||
return const_cast<decltype(std::declval<T>()[std::declval<U>()])>(sprout::as_const(x)[SPROUT_FORWARD(U, y)]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// container_traits
|
// container_traits
|
||||||
//
|
//
|
||||||
|
@ -60,10 +42,6 @@ namespace sprout {
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef sprout::detail::container_range_traits_default<std::array<T, N> > base_type;
|
typedef sprout::detail::container_range_traits_default<std::array<T, N> > base_type;
|
||||||
public:
|
|
||||||
using base_type::range_front;
|
|
||||||
using base_type::range_back;
|
|
||||||
using base_type::range_at;
|
|
||||||
public:
|
public:
|
||||||
// iterators:
|
// iterators:
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> >::iterator
|
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> >::iterator
|
||||||
|
@ -82,27 +60,7 @@ namespace sprout {
|
||||||
range_end(std::array<T, N> const& cont) {
|
range_end(std::array<T, N> const& cont) {
|
||||||
return typename sprout::container_traits<std::array<T, N> const>::iterator(cont, cont.size());
|
return typename sprout::container_traits<std::array<T, N> const>::iterator(cont, cont.size());
|
||||||
}
|
}
|
||||||
// element access:
|
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> >::reference
|
|
||||||
range_front(std::array<T, N>& cont) {
|
|
||||||
typedef typename sprout::container_traits<std::array<T, N> >::reference type;
|
|
||||||
return const_cast<type>(base_type::range_front(sprout::as_const(cont)));
|
|
||||||
}
|
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> >::reference
|
|
||||||
range_back(std::array<T, N>& cont) {
|
|
||||||
typedef typename sprout::container_traits<std::array<T, N> >::reference type;
|
|
||||||
return const_cast<type>(base_type::range_back(sprout::as_const(cont)));
|
|
||||||
}
|
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> >::reference
|
|
||||||
range_at(std::array<T, N>& cont, typename sprout::container_traits<std::array<T, N> >::size_type i) {
|
|
||||||
typedef typename sprout::container_traits<std::array<T, N> >::reference type;
|
|
||||||
return const_cast<type>(base_type::range_at(sprout::as_const(cont), i));
|
|
||||||
}
|
|
||||||
// data access:
|
// data access:
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> >::pointer
|
|
||||||
range_data(std::array<T, N>& cont) {
|
|
||||||
return sprout::addressof(range_front(cont));
|
|
||||||
}
|
|
||||||
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> const>::pointer
|
static SPROUT_CONSTEXPR typename sprout::container_traits<std::array<T, N> const>::pointer
|
||||||
range_data(std::array<T, N> const& cont) {
|
range_data(std::array<T, N> const& cont) {
|
||||||
return sprout::addressof(range_front(cont));
|
return sprout::addressof(range_front(cont));
|
||||||
|
|
74
sprout/container/subscript_at.hpp
Normal file
74
sprout/container/subscript_at.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2011-2016 Bolero MURAKAMI
|
||||||
|
https://github.com/bolero-MURAKAMI/Sprout
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
=============================================================================*/
|
||||||
|
#ifndef SPROUT_CONTAINER_SUBSCRIPT_AT_HPP
|
||||||
|
#define SPROUT_CONTAINER_SUBSCRIPT_AT_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
|
#include <sprout/container/traits_fwd.hpp>
|
||||||
|
#include <sprout/container/container_traits.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
//
|
||||||
|
// subscript_at
|
||||||
|
//
|
||||||
|
// effect:
|
||||||
|
// sprout::container_range_traits<Container>::range_subscript_at(cont, i)
|
||||||
|
// [default]
|
||||||
|
// ADL callable range_subscript_at(cont, i) -> range_subscript_at(cont, i)
|
||||||
|
// [default]
|
||||||
|
// Container is T[N] -> cont[i]
|
||||||
|
// otherwise, Container is not const
|
||||||
|
// && sprout::is_const_cast_convertible<const_reference, reference>
|
||||||
|
// && (callable sprout::as_const(cont)[i]
|
||||||
|
// || callable sprout::as_const(cont).begin()
|
||||||
|
// || ADL(without sprout) callable begin(sprout::as_const(cont))
|
||||||
|
// )
|
||||||
|
// -> const_cast<reference>(sprout::subscript_at(sprout::as_const(cont), i))
|
||||||
|
// otherwise, callable cont[i] -> cont[i]
|
||||||
|
// otherwise -> *sprout::next(sprout::begin(cont), i)
|
||||||
|
//
|
||||||
|
template<typename Container>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||||
|
subscript_at(Container& cont, typename sprout::container_traits<Container>::size_type i) {
|
||||||
|
return sprout::container_range_traits<Container>::range_subscript_at(cont, i);
|
||||||
|
}
|
||||||
|
template<typename Container>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||||
|
subscript_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||||
|
return sprout::container_range_traits<Container const>::range_subscript_at(cont, i);
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<T[N]>::reference
|
||||||
|
subscript_at(T (& arr)[N], typename sprout::container_traits<T[N]>::size_type i) {
|
||||||
|
return sprout::container_range_traits<T[N]>::range_subscript_at(arr, i);
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::reference
|
||||||
|
subscript_at(T const (& arr)[N], typename sprout::container_traits<T const[N]>::size_type i) {
|
||||||
|
return sprout::container_range_traits<T const[N]>::range_subscript_at(arr, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// csubscript_at
|
||||||
|
//
|
||||||
|
template<typename Container>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||||
|
csubscript_at(Container const& cont, typename sprout::container_traits<Container const>::size_type i) {
|
||||||
|
return sprout::subscript_at(cont, i);
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::reference
|
||||||
|
csubscript_at(T const (& arr)[N], typename sprout::container_traits<T const[N]>::size_type i) {
|
||||||
|
return sprout::subscript_at(arr, i);
|
||||||
|
}
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#include <sprout/container/container_range_traits.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_CONTAINER_SUBSCRIPT_AT_HPP
|
37
sprout/detail/functional/const_subscript.hpp
Normal file
37
sprout/detail/functional/const_subscript.hpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2011-2016 Bolero MURAKAMI
|
||||||
|
https://github.com/bolero-MURAKAMI/Sprout
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
=============================================================================*/
|
||||||
|
#ifndef SPROUT_DETAIL_FUNCTIONAL_CONST_SUBSCRIPT_HPP
|
||||||
|
#define SPROUT_DETAIL_FUNCTIONAL_CONST_SUBSCRIPT_HPP
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/utility/forward.hpp>
|
||||||
|
#include <sprout/utility/as_const.hpp>
|
||||||
|
#include <sprout/functional/transparent.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T = void>
|
||||||
|
struct const_subscript;
|
||||||
|
template<>
|
||||||
|
struct const_subscript<void>
|
||||||
|
: public sprout::transparent<>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename T, typename U>
|
||||||
|
SPROUT_CONSTEXPR decltype(std::declval<T>()[std::declval<U>()])
|
||||||
|
operator()(T&& x, U&& y)
|
||||||
|
const SPROUT_NOEXCEPT_IF_EXPR(const_cast<decltype(std::declval<T>()[std::declval<U>()])>(sprout::as_const(std::declval<T>())[std::declval<U>()]))
|
||||||
|
{
|
||||||
|
return const_cast<decltype(std::declval<T>()[std::declval<U>()])>(sprout::as_const(x)[SPROUT_FORWARD(U, y)]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_DETAIL_FUNCTIONAL_CONST_SUBSCRIPT_HPP
|
Loading…
Reference in a new issue