sv_concat, next version
From
Bonita Montero@Bonita.Montero@gmail.com to
comp.lang.c++ on Tue Oct 1 19:54:36 2024
From Newsgroup: comp.lang.c++
This is the next version of my sv_concat function which concatenates
everything which is convertible to a string_view. It's somewhat faster
since it uses basic_string<>::resize_and_overwrite which prevents mul-
tiple capacity-checks while adding the "viewables".
#pragma once
#include <type_traits>
#include <concepts>
#include <string_view>
#include <array>
#include <span>
#include <algorithm>
template<typename String, typename ... Viewables>
requires std::same_as<String, std::basic_string<typename String::value_type, typename String::traits_type, typename String::allocator_type>>
&& (std::convertible_to<Viewables, std::basic_string_view<typename
String::value_type, typename String::traits_type>> && ...)
inline String sv_concat( Viewables const &... viewables )
{
using namespace std;
String str;
constexpr size_t N = sizeof ...(Viewables);
if constexpr( N )
{
using sv_type = basic_string_view<typename String::value_type, typename String::traits_type>;
array<sv_type, N> views = { (sv_type)viewables ... };
[&]<size_t ... Indices>( index_sequence<Indices ...> )
{
size_t n = (views[Indices].length() + ...);
#if !defined(__cpp_lib_string_resize_and_overwrite)
str.reserve( n );
((str += views[Indices]), ...);
#else
str.resize_and_overwrite( n, [&]( String::value_type *p, size_t n )
{
auto where = span( p, n ).begin();
((where = copy( views[Indices].begin(), views[Indices].end(), where
)), ...);
return n;
} );
#endif
}( make_index_sequence<N>() );
}
return str;
}
I'm using a span-dervived iterator inside the lambda of resize_and
_overwrite to have iterator-debugging while adding the views. That's
a pattern I try to employ most of the time while using raw pointers;
when calculating beyond the bounds I get a runtime error while debug-
ging.
--- Synchronet 3.20a-Linux NewsLink 1.114
From
Bonita Montero@Bonita.Montero@gmail.com to
comp.lang.c++ on Tue Oct 8 17:58:03 2024
From Newsgroup: comp.lang.c++
I think this the final version. I don't know how to make it shorter.
template<typename String, typename ... Viewables>
requires std::same_as<String, std::basic_string<typename String::value_type, typename String::traits_type, typename String::allocator_type>>
&& (std::convertible_to<Viewables, std::basic_string_view<typename
String::value_type, typename String::traits_type>> && ...)
inline String sv_concat( Viewables const &... viewables )
{
using namespace std;
String str;
if constexpr( sizeof ...(Viewables) )
[&]( auto &&... views )
{
#if defined(__cpp_lib_string_resize_and_overwrite)
str.resize_and_overwrite( (views.length() + ...), [&]( String::value_type *p, size_t n )
{
auto where = span( p, n ).begin();
((where = copy( views.begin(), views.end(), where )), ...);
return n;
} );
#else
str.reserve( (views.length() + ...) );
((str += views), ...);
#endif
}( basic_string_view<typename String::value_type, typename String::traits_type>( viewables ) ... );
return str;
}
--- Synchronet 3.20a-Linux NewsLink 1.114