// Distributed under the Boost Software License Version 1.0 https://www.boost.org/LICENSE_1_0.txt // Copyright Gero Peterhoff #ifndef INCLUDE_BOOST_ALGORITHM_STRING_CONCAT_HPP #define INCLUDE_BOOST_ALGORITHM_STRING_CONCAT_HPP #include #include #include #include #include #include #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) #include #endif namespace boost { namespace algorithm { namespace detail { template BOOST_FORCEINLINE constexpr boost::basic_string_view make_view(const std::basic_string& str) noexcept { using view_type = boost::basic_string_view; return view_type(str); } template BOOST_FORCEINLINE constexpr boost::basic_string_view make_view(const boost::basic_string_view& str) noexcept { return str; } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) template BOOST_FORCEINLINE constexpr boost::basic_string_view make_view(const std::basic_string_view& str) noexcept { using view_type = boost::basic_string_view; return view_type(str.data(), str.size()); } #endif template BOOST_FORCEINLINE constexpr boost::basic_string_view make_view(const Char* const str) noexcept { using view_type = boost::basic_string_view; return view_type(str); } template BOOST_FORCEINLINE constexpr auto make_view_tuple(const Strings&... strs) noexcept -> decltype(std::make_tuple(make_view(strs)...)) { return std::make_tuple(make_view(strs)...); } struct accumulate_view_size { size_t size = 0; template BOOST_FORCEINLINE BOOST_CXX20_CONSTEXPR void operator()(const View& v) noexcept { size += v.size(); } }; template struct concat_view { String& value; typename String::iterator position; concat_view() = delete; BOOST_FORCEINLINE BOOST_CXX20_CONSTEXPR concat_view(String& res, const size_t view_size) noexcept : value{res} { using difference_type = typename String::difference_type; const size_t size = value.size(); value.resize(view_size + size); position = std::next(value.begin(), difference_type(size)); } template BOOST_FORCEINLINE BOOST_CXX20_CONSTEXPR void operator()(const View& v) noexcept { position = std::copy(v.begin(), v.end(), position); } }; } // detail template inline BOOST_CXX20_CONSTEXPR void concat(String& res, const Strings&... strs) noexcept { const auto tup = detail::make_view_tuple(strs...); detail::accumulate_view_size acc; boost::mp11::tuple_for_each(tup, acc); detail::concat_view ccv(res, acc.size); boost::mp11::tuple_for_each(tup, ccv); } template inline BOOST_CXX20_CONSTEXPR String concat_copy(const Strings&... strs) noexcept { String res; concat(res, strs...); return res; } } // algorithm } // boost #endif // INCLUDE_BOOST_ALGORITHM_STRING_CONCAT_HPP