/*============================================================================= 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_STD_ARRAY_HPP #define SPROUT_CONTAINER_STD_ARRAY_HPP #include #include #include #include #include #include #include #include #include #include #include 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 // template struct container_traits > : public sprout::detail::container_traits_default > { public: typedef sprout::index_iterator&, true, sprout::detail::const_subscript<> > iterator; typedef sprout::index_iterator const&, true, sprout::detail::const_subscript<> > const_iterator; }; // // container_range_traits // template 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); } static SPROUT_CONSTEXPR typename sprout::container_traits const>::iterator 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()); } static SPROUT_CONSTEXPR typename sprout::container_traits const>::iterator 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 // #ifndef SPROUT_CONTAINER_STD_ARRAY_HPP