/*============================================================================= Copyright (c) 2011-2019 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_STRING_CONCAT_HPP #define SPROUT_STRING_CONCAT_HPP #include #include #include #include #include #include namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR sprout::basic_string string_concat( sprout::basic_string const& lhs, std::size_t lsize, T const& rhs, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( lsize + 1, (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + 1 ? rhs : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_concat( T const& lhs, sprout::basic_string const& rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( 1 + rsize, (Indexes < 1 ? lhs : Indexes < 1 + rsize ? rhs[Indexes - 1] : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_concat( sprout::basic_string const& lhs, std::size_t lsize, T const (& rhs)[M], std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( lsize + rsize, (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + rsize ? rhs[Indexes - lsize] : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_concat( T const (& lhs)[M], std::size_t lsize, sprout::basic_string const& rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( lsize + rsize, (Indexes < lsize ? *(lhs + Indexes) : Indexes < lsize + rsize ? rhs[Indexes - lsize] : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_concat( sprout::basic_string const& lhs, std::size_t lsize, sprout::basic_string const& rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( lsize + rsize, (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + rsize ? rhs[Indexes - lsize] : T() )... ); } } // namespace detail // // operator+ // template inline SPROUT_CONSTEXPR sprout::basic_string operator+(sprout::basic_string const& lhs, T const& rhs) { return sprout::detail::string_concat( lhs, lhs.size(), rhs, sprout::make_index_tuple::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator+(T const& lhs, sprout::basic_string const& rhs) { return sprout::detail::string_concat( lhs, rhs, rhs.size(), sprout::make_index_tuple<1 + N>::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator+(sprout::basic_string const& lhs, T const (& rhs)[M]) { typedef sprout::char_traits_helper traits_type; return sprout::detail::string_concat( lhs, lhs.size(), rhs, traits_type::length(rhs, M - 1), sprout::make_index_tuple::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator+(T const (& lhs)[M], sprout::basic_string const& rhs) { typedef sprout::char_traits_helper traits_type; return sprout::detail::string_concat( lhs, traits_type::length(lhs, M - 1), rhs, rhs.size(), sprout::make_index_tuple<(M - 1) + N>::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator+(sprout::basic_string const& lhs, sprout::basic_string const& rhs) { return sprout::detail::string_concat( lhs, lhs.size(), rhs, rhs.size(), sprout::make_index_tuple::make() ); } } // namespace sprout #endif // #ifndef SPROUT_STRING_CONCAT_HPP