#ifndef SPROUT_CONTAINER_CONTAINER_TRAITS_CONSTRUCT_TRAITS_HPP #define SPROUT_CONTAINER_CONTAINER_TRAITS_CONSTRUCT_TRAITS_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include namespace sprout { // // container_construct_traits // template struct container_construct_traits; namespace detail { template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::is_fixed_container::value, typename sprout::container_construct_traits::copied_type >::type default_make_container(Args&&... args) { typedef typename sprout::container_construct_traits::copied_type copied_type; return copied_type{{sprout::forward(args)...}}; } template inline SPROUT_CONSTEXPR typename std::enable_if< !sprout::is_fixed_container::value, typename sprout::container_construct_traits::copied_type >::type default_make_container(Args&&... args) { typedef typename sprout::container_construct_traits::copied_type copied_type; return copied_type{sprout::forward(args)...}; } template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::is_fixed_container::value, typename sprout::container_construct_traits::copied_type >::type default_remake_container(Cont&& cont, typename sprout::container_traits::difference_type size, Args&&... args) { return sprout::container_construct_traits::make(sprout::forward(args)...); } template inline SPROUT_CONSTEXPR typename std::enable_if< !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) { return sprout::container_construct_traits::make(sprout::forward(args)...); } template inline SPROUT_CONSTEXPR typename std::enable_if< !sprout::is_fixed_container::value, typename sprout::container_construct_traits::copied_type >::type default_remake_container(Cont&& cont, typename sprout::container_traits::difference_type size, InputIterator first, InputIterator last) { typedef typename sprout::container_construct_traits::copied_type copied_type; return copied_type( sprout::make_remake_iterator( sprout::internal_begin(cont), first, first, last, sprout::internal_begin_offset(cont), sprout::internal_end_offset(cont) ), sprout::make_remake_iterator( sprout::internal_end(cont), last, first, last, sprout::internal_begin_offset_backward(cont), sprout::internal_end_offset_backward(cont) ) ); } template struct container_construct_traits_impl { public: typedef Container copied_type; public: template static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { return sprout::forward(cont); } template static SPROUT_CONSTEXPR copied_type make(Args&&... args) { return sprout::detail::default_make_container(sprout::forward(args)...); } template static SPROUT_CONSTEXPR copied_type remake(Cont&& cont, typename sprout::container_traits::difference_type size, Args&&... args) { return sprout::detail::default_remake_container( sprout::forward(cont), size, sprout::forward(args)... ); } }; } // namespace detail template struct container_construct_traits : public sprout::detail::container_construct_traits_impl {}; template struct container_construct_traits : public sprout::container_construct_traits {}; } // namespace sprout #endif // #ifndef SPROUT_CONTAINER_CONTAINER_CONSTRUCT_TRAITS_HPP