/*============================================================================= Copyright (c) 2011-2017 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_RATIONAL_CONTAINER_HPP #define SPROUT_RATIONAL_CONTAINER_HPP #include #include #include #include #include #include #include namespace sprout { namespace detail { struct rational_at { public: template SPROUT_CONSTEXPR typename Rational::value_type operator()(Rational const& c, Index i) const { return i == 0 ? c.numerator() : i == 1 ? c.denominator() : throw std::out_of_range("rational_at: index out of range") ; } }; } // namespace detail // // container_traits // template struct container_traits > { public: typedef T value_type; typedef sprout::index_iterator&, true, sprout::detail::rational_at> iterator; typedef sprout::index_iterator const&, true, sprout::detail::rational_at> const_iterator; typedef T reference; typedef T const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef T const* const_pointer; public: SPROUT_STATIC_CONSTEXPR size_type static_size = 2; public: static SPROUT_CONSTEXPR size_type fixed_size() SPROUT_NOEXCEPT { return static_size; } }; template SPROUT_CONSTEXPR_OR_CONST typename sprout::container_traits >::size_type sprout::container_traits >::static_size; // // container_range_traits // template struct container_range_traits > : public sprout::container_range_traits_default > { public: static SPROUT_CONSTEXPR typename sprout::container_traits >::iterator range_begin(sprout::rational& cont) { return typename sprout::container_traits >::iterator(cont, 0); } static SPROUT_CONSTEXPR typename sprout::container_traits const>::iterator range_begin(sprout::rational const& cont) { return typename sprout::container_traits const>::iterator(cont, 0); } static SPROUT_CONSTEXPR typename sprout::container_traits >::iterator range_end(sprout::rational& cont) { return typename sprout::container_traits >::iterator(cont, 2); } static SPROUT_CONSTEXPR typename sprout::container_traits const>::iterator range_end(sprout::rational const& cont) { return typename sprout::container_traits const>::iterator(cont, 2); } }; // // container_construct_traits // template struct container_construct_traits > { public: typedef sprout::rational copied_type; public: template static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { return SPROUT_FORWARD(Cont, cont); } template static SPROUT_CONSTEXPR copied_type make(Args&&... args) { return copied_type(SPROUT_FORWARD(Args, args)...); } template static SPROUT_CONSTEXPR copied_type remake(Cont&&, typename sprout::container_traits >::difference_type, Args&&... args) { return copied_type(SPROUT_FORWARD(Args, args)...); } }; // // container_transform_traits // template struct container_transform_traits > { public: template struct rebind_type { public: typedef sprout::rational type; }; }; } // namespace sprout #endif // #ifndef SPROUT_RATIONAL_CONTAINER_HPP