#ifndef SPROUT_RANGE_RANGE_CONTAINER_HPP #define SPROUT_RANGE_RANGE_CONTAINER_HPP #include #include #include #include #include #include namespace sprout { namespace range { // // range_container // template struct range_container : public sprout::container_traits { 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::remove_reference::type const& 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::remove_pointer::type const* const_pointer; private: iterator first_; iterator last_; public: // construct/copy/destroy: range_container() = default; SPROUT_CONSTEXPR range_container(iterator first, iterator last) : first_(first) , last_(last) {} template void swap(range_container& other) { using std::swap; swap(other.first_, first_); 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 range_container& operator=(range_container const& rhs) { first_ = rhs.first_; last_ = rhs.last_; return *this; } template range_container& operator=(range_container&& rhs) { first_ = std::move(rhs.first_); last_ = std::move(rhs.last_); return *this; } }; // // swap // template inline void swap(sprout::range::range_container& lhs, sprout::range::range_container& rhs) { lhs.swap(rhs); } // // is_range_container // template struct is_range_container : public std::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 std::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)), sprout::end(sprout::forward(range)) ); } } // namespace range // // container_traits // template struct container_traits > : public sprout::detail::container_traits_default > {}; } // namespace sprout #endif // #ifndef SPROUT_RANGE_RANGE_CONTAINER_HPP