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
|
||||
#define SPROUT_ADAPT_BOOST_ARRAY_HPP
|
||||
|
||||
#include <array>
|
||||
#include <boost/array.hpp>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/boost/array.hpp>
|
||||
#include <sprout/functional/hash/boost/array.hpp>
|
||||
|
|
|
@ -26,12 +26,14 @@ namespace sprout {
|
|||
// otherwise, Container is not const
|
||||
// && sprout::is_const_cast_convertible<const_reference, reference>
|
||||
// && (callable sprout::as_const(cont).at(i)
|
||||
// || 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::at(sprout::as_const(cont), 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>
|
||||
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::reference
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <type_traits>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/range_index_check.hpp>
|
||||
#include <sprout/iterator/index_iterator.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/functional/transparent.hpp>
|
||||
|
@ -101,13 +102,21 @@ namespace sprout {
|
|||
return cont.elems[N - 1];
|
||||
}
|
||||
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];
|
||||
}
|
||||
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];
|
||||
}
|
||||
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:
|
||||
static SPROUT_CONSTEXPR typename sprout::container_traits<boost::array<T, N> >::pointer
|
||||
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_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
|
||||
|
|
|
@ -14,6 +14,5 @@
|
|||
#include <sprout/container/construct_functions.hpp>
|
||||
#include <sprout/container/fitness_functions.hpp>
|
||||
#include <sprout/container/sub_functions.hpp>
|
||||
#include <sprout/container/shrink_to_fit.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_CONTAINER_FUNCTIONS_HPP
|
||||
|
|
|
@ -20,5 +20,7 @@
|
|||
#include <sprout/container/nth.hpp>
|
||||
#include <sprout/container/index_of.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
|
||||
|
|
|
@ -66,6 +66,16 @@ namespace sprout {
|
|||
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::reference
|
||||
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
|
||||
//
|
||||
|
@ -105,8 +115,21 @@ namespace sprout {
|
|||
template<typename Container>
|
||||
SPROUT_CONSTEXPR typename sprout::container_traits<Container const>::pointer
|
||||
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/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/container/traits.hpp>
|
||||
# include <sprout/iterator/index_iterator.hpp>
|
||||
# include <sprout/detail/functional/const_subscript.hpp>
|
||||
#endif
|
||||
|
||||
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
||||
|
@ -27,8 +28,8 @@ namespace sprout {
|
|||
: public sprout::detail::container_traits_default<sscrisk::cel::array<T, N> >
|
||||
{
|
||||
public:
|
||||
typedef sprout::index_iterator<sscrisk::cel::array<T, N>&, true> iterator;
|
||||
typedef sprout::index_iterator<sscrisk::cel::array<T, N> const&, true> const_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, sprout::detail::const_subscript<> > const_iterator;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
@ -18,27 +18,9 @@
|
|||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/utility/as_const.hpp>
|
||||
#include <sprout/memory/addressof.hpp>
|
||||
#include <sprout/functional/transparent.hpp>
|
||||
#include <sprout/detail/functional/const_subscript.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
|
||||
|
||||
//
|
||||
// container_traits
|
||||
//
|
||||
|
@ -60,10 +42,6 @@ namespace sprout {
|
|||
{
|
||||
private:
|
||||
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:
|
||||
// iterators:
|
||||
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) {
|
||||
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:
|
||||
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
|
||||
range_data(std::array<T, N> const& 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