From 14865d4d644e4d0386b28003cd3761da016cca75 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 16 Apr 2016 18:59:02 +0900 Subject: [PATCH] fix std::array adapt --- sprout/container/container_range_traits.hpp | 10 +-- sprout/container/std/array.hpp | 73 ++++++++++++++++--- sprout/tuple/std/array.hpp | 3 +- .../type_traits/is_within_tag_namespace.hpp | 4 +- 4 files changed, 70 insertions(+), 20 deletions(-) diff --git a/sprout/container/container_range_traits.hpp b/sprout/container/container_range_traits.hpp index 62698769..fc88e1ca 100644 --- a/sprout/container/container_range_traits.hpp +++ b/sprout/container/container_range_traits.hpp @@ -632,7 +632,7 @@ namespace sprout { typename sprout::container_traits::size_type >::type range_index_of_impl(Container& cont, typename sprout::container_traits::iterator p) { - return sprout::distance(begin(cont), p); + return sprout::distance(sprout::begin(cont), p); } template inline SPROUT_CONSTEXPR typename std::enable_if< @@ -648,7 +648,7 @@ namespace sprout { typename sprout::container_traits::size_type >::type range_index_of_impl(Container const& cont, typename sprout::container_traits::iterator p) { - return sprout::distance(begin(cont), p); + return sprout::distance(sprout::begin(cont), p); } } // namespace detail } // namespace sprout @@ -658,24 +658,22 @@ namespace sprout_container_range_detail { inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator range_begin(Container& cont) { return sprout::detail::range_begin_impl(cont); -// return cont.begin(); } template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator range_begin(Container const& cont) { return sprout::detail::range_begin_impl(cont); -// return cont.begin(); } template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator range_end(Container& cont) { - return cont.end(); + return sprout::detail::range_end_impl(cont); } template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator range_end(Container const& cont) { - return cont.end(); + return sprout::detail::range_end_impl(cont); } template diff --git a/sprout/container/std/array.hpp b/sprout/container/std/array.hpp index 4516058c..3c4d84ae 100644 --- a/sprout/container/std/array.hpp +++ b/sprout/container/std/array.hpp @@ -9,16 +9,37 @@ #define SPROUT_CONTAINER_STD_ARRAY_HPP #include +#include +#include #include -#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION -# include -# include -# include -# include -#endif +#include +#include +#include +#include +#include +#include +#include -#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION namespace sprout { + namespace detail { + template + struct const_subscript; + template<> + struct const_subscript + : public sprout::transparent<> + { + public: + template + SPROUT_CONSTEXPR decltype(std::declval()[std::declval()]) + operator()(T&& x, U&& y) + const SPROUT_NOEXCEPT_IF_EXPR(std::declval()[std::declval()]) + { + typedef decltype(std::declval()[std::declval()]) type; + return const_cast(sprout::as_const(x)[SPROUT_FORWARD(U, y)]); + } + }; + } // namespace detail + // // container_traits // @@ -27,8 +48,8 @@ namespace sprout { : public sprout::detail::container_traits_default > { public: - typedef sprout::index_iterator&, true> iterator; - typedef sprout::index_iterator const&, true> const_iterator; + typedef sprout::index_iterator&, true, sprout::detail::const_subscript<> > iterator; + typedef sprout::index_iterator const&, true, sprout::detail::const_subscript<> > const_iterator; }; // @@ -38,7 +59,14 @@ namespace sprout { struct container_range_traits > : public sprout::detail::container_range_traits_default > { + private: + typedef sprout::detail::container_range_traits_default > 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 >::iterator range_begin(std::array& cont) { return typename sprout::container_traits >::iterator(cont, 0); @@ -47,7 +75,6 @@ namespace sprout { range_begin(std::array const& cont) { return typename sprout::container_traits const>::iterator(cont, 0); } - static SPROUT_CONSTEXPR typename sprout::container_traits >::iterator range_end(std::array& cont) { return typename sprout::container_traits >::iterator(cont, cont.size()); @@ -56,8 +83,32 @@ namespace sprout { range_end(std::array const& cont) { return typename sprout::container_traits const>::iterator(cont, cont.size()); } + // element access: + static SPROUT_CONSTEXPR typename sprout::container_traits >::reference + range_front(std::array& cont) { + typedef typename sprout::container_traits >::reference type; + return const_cast(base_type::range_front(sprout::as_const(cont))); + } + static SPROUT_CONSTEXPR typename sprout::container_traits >::reference + range_back(std::array& cont) { + typedef typename sprout::container_traits >::reference type; + return const_cast(base_type::range_back(sprout::as_const(cont))); + } + static SPROUT_CONSTEXPR typename sprout::container_traits >::reference + range_at(std::array& cont, typename sprout::container_traits >::size_type i) { + typedef typename sprout::container_traits >::reference type; + return const_cast(base_type::range_at(sprout::as_const(cont), i)); + } + // data access: + static SPROUT_CONSTEXPR typename sprout::container_traits >::pointer + range_data(std::array& cont) { + return sprout::addressof(range_front(cont)); + } + static SPROUT_CONSTEXPR typename sprout::container_traits const>::pointer + range_data(std::array const& cont) { + return sprout::addressof(range_front(cont)); + } }; } // namespace sprout -#endif #endif // #ifndef SPROUT_CONTAINER_STD_ARRAY_HPP diff --git a/sprout/tuple/std/array.hpp b/sprout/tuple/std/array.hpp index 65e0b253..7e580045 100644 --- a/sprout/tuple/std/array.hpp +++ b/sprout/tuple/std/array.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -28,7 +29,7 @@ namespace sprout { static SPROUT_CONSTEXPR T& tuple_get(std::array& t) SPROUT_NOEXCEPT { static_assert(I < N, "tuple_get: index out of range"); - return t[I]; + return const_cast(sprout::as_const(t)[I]); } template static SPROUT_CONSTEXPR T const& diff --git a/sprout/type_traits/is_within_tag_namespace.hpp b/sprout/type_traits/is_within_tag_namespace.hpp index cf9dcfba..7689547a 100644 --- a/sprout/type_traits/is_within_tag_namespace.hpp +++ b/sprout/type_traits/is_within_tag_namespace.hpp @@ -46,10 +46,10 @@ struct SPROUT_PP_CAT(is_within_namespace_, NAME) \ : public sprout::is_within_tag_namespace \ {}; \ - SPROUT_IS_WITHIN_NAMESPACE_V(NAME, NAMESPACE); + SPROUT_IS_WITHIN_NAMESPACE_V(NAME, NAMESPACE) #if SPROUT_USE_VARIABLE_TEMPLATES # define SPROUT_IS_WITHIN_NAMESPACE_V(NAME, NAMESPACE) \ - template + template \ SPROUT_STATIC_CONSTEXPR bool SPROUT_PP_CAT(SPROUT_PP_CAT(is_within_namespace_, NAME), _v) = SPROUT_PP_CAT(is_within_namespace_, NAME)::value #else // #if SPROUT_USE_VARIABLE_TEMPLATES # define SPROUT_IS_WITHIN_NAMESPACE_V(NAME, NAMESPACE) \