diff --git a/sprout/container/container_construct_traits.hpp b/sprout/container/container_construct_traits.hpp index ddc59f0b..6e814c9f 100644 --- a/sprout/container/container_construct_traits.hpp +++ b/sprout/container/container_construct_traits.hpp @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include namespace sprout { // @@ -50,7 +52,9 @@ namespace sprout { } template inline SPROUT_CONSTEXPR typename std::enable_if< - !sprout::is_fixed_container::value && sizeof...(Args) != 2, + !sprout::is_fixed_container::value + && !(sizeof...(Args) == 2 && sprout::tpp::all_of::type>...>::value) + , typename sprout::container_construct_traits::copied_type >::type default_remake_container(Cont&& cont, typename sprout::container_traits::difference_type size, Args&&... args) { diff --git a/sprout/iterator/insert_iterator.hpp b/sprout/iterator/insert_iterator.hpp new file mode 100644 index 00000000..2a3a6d10 --- /dev/null +++ b/sprout/iterator/insert_iterator.hpp @@ -0,0 +1,175 @@ +#ifndef SPROUT_ITERATOR_INSERT_ITERATOR_HPP +#define SPROUT_ITERATOR_INSERT_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // insert_iterator + // + template + class 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; + iterator iter; + public: + SPROUT_CONSTEXPR insert_iterator() = default; + SPROUT_CONSTEXPR insert_iterator(param_type x, iterator pos) + : base_type(x), iter(pos) + {} + SPROUT_CONSTEXPR insert_iterator(insert_iterator const&) = default; + SPROUT_CONSTEXPR iterator position() const { + return iter; + } + insert_iterator& operator=(typename container_type::value_type const& value) { + container->insert(iter, value); + return *this; + } + insert_iterator& operator=(typename container_type::value_type&& value) { + container->insert(iter, sprout::move(value)); + return *this; + } + SPROUT_CONSTEXPR insert_iterator const& operator*() const { + return *this; + } + insert_iterator& operator*() { + return *this; + } + insert_iterator& operator++() { + return *this; + } + insert_iterator operator++(int) { + return *this; + } + + void swap(insert_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(base_type::swap(other)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(other.iter, iter)) + ) + { + base_type::swap(other); + sprout::swap(other.iter, iter); + } + }; + + // + // swap + // + template + inline void + swap(sprout::insert_iterator& lhs, sprout::insert_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // inserter + // + template + inline SPROUT_CONSTEXPR sprout::insert_iterator + inserter(Container& x, typename sprout::insert_iterator::iterator pos) { + return sprout::insert_iterator(x, pos); + } + template + inline SPROUT_CONSTEXPR sprout::insert_iterator + inserter(Container const& x, typename sprout::insert_iterator::iterator pos) { + return sprout::insert_iterator(x, pos); + } + + // + // 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(Iterator pos, Cont&& cont, typename sprout::container_traits::difference_type size, InputIterator first, InputIterator last) { + return sprout::make( + sprout::make_insert_range_iterator( + sprout::internal_begin(cont), pos, + first, first, last + ), + sprout::make_insert_range_iterator( + sprout::internal_end(cont), pos, + 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 size, Args&&... args) { + return remake_impl(cont.position(), sprout::get_internal(sprout::forward(cont)), size, 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_INSERT_ITERATOR_HPP diff --git a/sprout/iterator/inserter.hpp b/sprout/iterator/inserter.hpp index 8e834d88..01b90dd5 100644 --- a/sprout/iterator/inserter.hpp +++ b/sprout/iterator/inserter.hpp @@ -4,5 +4,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_ITERATOR_INSERTER_HPP diff --git a/sprout/iterator/type_traits/is_iterator.hpp b/sprout/iterator/type_traits/is_iterator.hpp index 7dfe6021..4f9c4bf2 100644 --- a/sprout/iterator/type_traits/is_iterator.hpp +++ b/sprout/iterator/type_traits/is_iterator.hpp @@ -16,91 +16,121 @@ namespace sprout { // // is_iterator // - template + template struct is_iterator - : public sprout::detail::has_iterator_category > + : public sprout::detail::has_iterator_category > + {}; + + // + // is_iterator_category_of + // + template + struct is_iterator_category_of + : public std::is_convertible {}; // // is_input_iterator_category // - template + template struct is_input_iterator_category - : public std::is_convertible + : public sprout::is_iterator_category_of {}; // // is_output_iterator_category // - template + template struct is_output_iterator_category - : public std::is_convertible + : public sprout::is_iterator_category_of {}; // // is_forward_iterator_category // - template + template struct is_forward_iterator_category - : public std::is_convertible + : public sprout::is_iterator_category_of {}; // // is_bidirectional_iterator_category // - template + template struct is_bidirectional_iterator_category - : public std::is_convertible + : public sprout::is_iterator_category_of {}; // // is_random_access_iterator_category // - template + template struct is_random_access_iterator_category - : public std::is_convertible + : public sprout::is_iterator_category_of + {}; + + namespace detail { + template + struct is_iterator_of_impl + : public std::false_type + {}; + template + struct is_iterator_of_impl< + MaybeIterator, Category, + typename std::enable_if::value>::type + > + : public sprout::is_iterator_category_of::iterator_category, Category> + {}; + } // namespace detail + + // + // is_iterator_of + // + template + struct is_iterator_of + : public sprout::detail::is_iterator_of_impl {}; // // is_input_iterator // - template + template struct is_input_iterator - : public sprout::is_input_iterator_category::iterator_category> + : public sprout::is_iterator_of {}; // // is_output_iterator // - template + template struct is_output_iterator - : public sprout::is_output_iterator_category::iterator_category> + : public sprout::is_iterator_of {}; // // is_forward_iterator // - template + template struct is_forward_iterator - : public sprout::is_forward_iterator_category::iterator_category> + : public sprout::is_iterator_of {}; // // is_bidirectional_iterator // - template + template struct is_bidirectional_iterator - : public sprout::is_bidirectional_iterator_category::iterator_category> + : public sprout::is_iterator_of {}; // // is_random_access_iterator // - template + template struct is_random_access_iterator - : public sprout::is_random_access_iterator_category::iterator_category> + : public sprout::is_iterator_of {}; // // is_constant_distance_iterator // - template + template struct is_constant_distance_iterator : public std::integral_constant< bool, - sprout::is_random_access_iterator::value && !std::is_pointer::value + sprout::is_random_access_iterator::value && !std::is_pointer::value > {}; } // namespace sprout