add subscript_at function

This commit is contained in:
bolero-MURAKAMI 2016-04-17 19:36:56 +09:00
parent 8278a2642c
commit 0080332dd5
12 changed files with 341 additions and 54 deletions

View file

@ -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>

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>

View 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

View file

@ -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;
};
//

View file

@ -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));

View 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

View 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