/*============================================================================= Copyright (c) 2011-2013 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_ITERATOR_FRONT_INSERT_ITERATOR_HPP #define SPROUT_ITERATOR_FRONT_INSERT_ITERATOR_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include namespace sprout { // // front_insert_iterator // template class front_insert_iterator : public std::iterator , public sprout::container_holder { private: typedef sprout::container_holder base_type; public: typedef typename base_type::container_type container_type; typedef typename base_type::internal_type internal_type; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::param_type param_type; typedef typename base_type::const_param_type const_param_type; typedef typename base_type::holder_type holder_type; protected: using base_type::container; public: front_insert_iterator() = default; explicit SPROUT_CONSTEXPR front_insert_iterator(param_type x) : base_type(x) {} SPROUT_CONSTEXPR front_insert_iterator(front_insert_iterator const&) = default; SPROUT_CXX14_CONSTEXPR front_insert_iterator& operator=(typename container_type::value_type const& value) { container->push_front(value); return *this; } SPROUT_CXX14_CONSTEXPR front_insert_iterator& operator=(typename container_type::value_type&& value) { container->push_front(sprout::move(value)); return *this; } SPROUT_CXX14_CONSTEXPR front_insert_iterator& operator*() { return *this; } SPROUT_CXX14_CONSTEXPR front_insert_iterator& operator++() { return *this; } SPROUT_CXX14_CONSTEXPR front_insert_iterator operator++(int) { return *this; } void swap(front_insert_iterator& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(base_type::swap(other))) { base_type::swap(other); } }; // // swap // template inline SPROUT_CXX14_CONSTEXPR void swap(sprout::front_insert_iterator& lhs, sprout::front_insert_iterator& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { lhs.swap(rhs); } // // front_inserter // template inline SPROUT_CONSTEXPR sprout::front_insert_iterator front_inserter(Container& x) { return sprout::front_insert_iterator(x); } template inline SPROUT_CONSTEXPR sprout::front_insert_iterator front_inserter(Container const& x) { return sprout::front_insert_iterator(x); } // // container_construct_traits // template struct container_construct_traits > { public: typedef typename sprout::container_construct_traits::copied_type copied_type; private: template static SPROUT_CONSTEXPR copied_type remake_impl(Cont&& cont, InputIterator first, InputIterator last) { return sprout::make( sprout::make_insert_range_iterator( sprout::internal_begin(cont), sprout::begin(cont), first, first, last ), sprout::make_insert_range_iterator( sprout::internal_end(cont), sprout::begin(cont), last, first, last ) ); } public: template static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { return sprout::deep_copy(sprout::get_internal(sprout::forward(cont))); } template static SPROUT_CONSTEXPR copied_type make(Args&&... args) { return sprout::make(sprout::forward(args)...); } template static SPROUT_CONSTEXPR copied_type remake(Cont&& cont, typename sprout::container_traits::difference_type, Args&&... args) { return remake_impl(sprout::get_internal(sprout::forward(cont)), sprout::forward(args)...); } }; // // container_fitness_traits // template struct container_fitness_traits > { public: template static SPROUT_CONSTEXPR typename sprout::container_traits::difference_type fit_size(Cont&& cont, typename sprout::container_traits::difference_type size) { return size + sprout::size(sprout::forward(cont)); } }; // // sub_container_traits // template struct sub_container_traits > : public sprout::sub_container_traits > {}; } // namespace sprout #endif // #ifndef SPROUT_ITERATOR_FRONT_INSERT_ITERATOR_HPP