• 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