/*============================================================================= Copyright (c) 2011-2019 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_RANGE_RANGE_CONTAINER_HPP #define SPROUT_RANGE_RANGE_CONTAINER_HPP #include #include #include #include #include #include #include #include #include #include namespace sprout { namespace range { // // range_container // template struct range_container : public sprout::container_traits_facade { public: typedef Iterator iterator; typedef iterator const_iterator; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::reference reference; typedef typename std::conditional< std::is_reference::value, typename std::remove_reference::type const&, reference >::type const_reference; typedef typename std::iterator_traits::difference_type difference_type; typedef typename std::make_unsigned::type size_type; typedef typename std::iterator_traits::pointer pointer; typedef typename std::conditional< std::is_pointer::value, typename std::remove_pointer::type const*, pointer >::type const_pointer; private: iterator first_; iterator last_; public: // construct/copy/destroy: SPROUT_CONSTEXPR range_container() : first_(), last_() {} SPROUT_CONSTEXPR range_container(iterator const& first, iterator const& last) : first_(first), last_(last) {} template SPROUT_CXX14_CONSTEXPR void swap(range_container& other) SPROUT_NOEXCEPT_IF( SPROUT_NOEXCEPT_EXPR(sprout::swap(other.first_, first_)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(other.last_, last_)) ) { sprout::swap(other.first_, first_); sprout::swap(other.last_, last_); } // iterators: SPROUT_CONSTEXPR iterator begin() const { return first_; } SPROUT_CONSTEXPR iterator end() const { return last_; } // capacity: SPROUT_CONSTEXPR size_type size() const { return sprout::distance(first_, last_); } SPROUT_CONSTEXPR bool empty() const { return first_ == last_; } // element access: SPROUT_CONSTEXPR reference operator[](size_type i) const { return *sprout::next(first_, i); } SPROUT_CONSTEXPR reference at(size_type i) const { return i < size() ? *sprout::next(first_, i) : (throw std::out_of_range("sprout::range::range_container<>: index out of range"), *sprout::next(first_, i)) ; } SPROUT_CONSTEXPR reference front() const { return *first_; } SPROUT_CONSTEXPR reference back() const { return *sprout::next(first_, size() - 1); } // others: template SPROUT_CXX14_CONSTEXPR range_container& operator=(range_container const& rhs) { first_ = rhs.first_; last_ = rhs.last_; return *this; } template SPROUT_CXX14_CONSTEXPR range_container& operator=(range_container&& rhs) { first_ = sprout::move(rhs.first_); last_ = sprout::move(rhs.last_); return *this; } }; // // swap // template inline SPROUT_CXX14_CONSTEXPR void swap(sprout::range::range_container& lhs, sprout::range::range_container& rhs) { lhs.swap(rhs); } // // is_range_container // template struct is_range_container : public sprout::false_type {}; template struct is_range_container : public sprout::range::is_range_container {}; template struct is_range_container : public sprout::range::is_range_container {}; template struct is_range_container : public sprout::range::is_range_container {}; template struct is_range_container > : public sprout::true_type {}; // // make_range_container // template inline SPROUT_CONSTEXPR sprout::range::range_container::type> make_range_container(Range&& range) { return sprout::range::range_container::type>( sprout::begin(SPROUT_FORWARD(Range, range)), sprout::end(SPROUT_FORWARD(Range, range)) ); } } // namespace range // // container_traits // template struct container_traits > : public sprout::container_traits_default > {}; } // namespace sprout #endif // #ifndef SPROUT_RANGE_RANGE_CONTAINER_HPP