diff --git a/sprout/string.hpp b/sprout/string.hpp index 79427945..5a6ed743 100644 --- a/sprout/string.hpp +++ b/sprout/string.hpp @@ -400,25 +400,93 @@ namespace sprout { }; }; + namespace detail { + // + // make_clone_functor_impl + // + template + struct make_clone_functor_impl; + + template + struct make_clone_functor_impl > { + private: + typedef sprout::basic_string container_type; + typedef typename sprout::fixed_container_traits::clone_type clone_type; + private: + template + static SPROUT_CONSTEXPR clone_type make_impl(typename clone_type::size_type size) { + return clone_type{{}, size}; + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + S != sizeof...(Args), + clone_type + >::type make_impl(typename clone_type::size_type size, T const& head, Args const&... tail) { + return make_impl(size, tail..., S < size ? head : T()); + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + S == sizeof...(Args), + clone_type + >::type make_impl(typename clone_type::size_type size, T const& head, Args const&... tail) { + return clone_type{{tail..., head}, size}; + } + public: + static SPROUT_CONSTEXPR typename clone_type::size_type length() { + return 0; + } + template + static SPROUT_CONSTEXPR typename clone_type::size_type length(T const& head, Tail const&... tail) { + return !head ? 0 : 1 + length(tail...); + } + template + static SPROUT_CONSTEXPR clone_type make(typename clone_type::size_type size, Args const&... args) { + return make_impl<0>(size, args...); + } + }; + } // namespace detail + // // make_clone_functor // template struct make_clone_functor > { private: - typedef typename sprout::fixed_container_traits >::clone_type clone_type; - private: - static SPROUT_CONSTEXPR typename clone_type::size_type length() { - return 0; - } - template - static SPROUT_CONSTEXPR typename clone_type::size_type length(T const& head, Tail const&... tail) { - return !head ? 0 : 1 + length(tail...); - } + typedef sprout::basic_string container_type; + typedef sprout::detail::make_clone_functor_impl impl_type; public: template - SPROUT_CONSTEXPR clone_type operator()(Args const&... args) const { - return clone_type{{args...}, length(args...)}; + SPROUT_CONSTEXPR typename sprout::fixed_container_traits::clone_type operator()(Args const&... args) const { + return impl_type::make(impl_type::length(args...), args...); + } + }; + + // + // remake_clone_functor + // + template + struct remake_clone_functor > { + private: + typedef sprout::basic_string container_type; + typedef sprout::detail::make_clone_functor_impl impl_type; + public: + template + SPROUT_CONSTEXPR typename sprout::fixed_container_traits::clone_type operator()( + Other& other, + typename sprout::fixed_container_traits::difference_type size, + Args const&... args + ) const + { + return impl_type::make(size, args...); + } + template + SPROUT_CONSTEXPR typename sprout::fixed_container_traits::clone_type operator()( + Other const& other, + typename sprout::fixed_container_traits::difference_type size, + Args const&... args + ) const + { + return impl_type::make(size, args...); } }; diff --git a/sprout/sub_array.hpp b/sprout/sub_array.hpp index 5d7fcd93..71ab54be 100644 --- a/sprout/sub_array.hpp +++ b/sprout/sub_array.hpp @@ -399,7 +399,7 @@ namespace sprout { // swap // template - SPROUT_CONSTEXPR inline void swap(sprout::sub_array& lhs, sprout::sub_array& rhs) { + inline void swap(sprout::sub_array& lhs, sprout::sub_array& rhs) { lhs.swap(rhs); } @@ -934,3 +934,4 @@ namespace std { } // namespace std #endif // #ifndef SPROUT_SUB_ARRAY_HPP +