Bonita Montero
2024-05-29 17:01:59 UTC
I sometimes needed a function to concatenate an arbitrary number of
string_views to a string. The problem with that that variadic functions
only work with generic types. So I can't write sth. like:
#include <string_view>
#include <string>
using namespace std;
template<typename Allocator, typename Char, typename Traits>
auto sv_concat( basic_string_view<Char, Traits> svs ... )
{
basic_string<Char, Traits, Allocator> str;
str.reserve( (svs.length() + ...) );
((str += svs), ...);
return str;
}
So I did this genrically and I constrained the generic types to
actually be string_views. I made some header out of that which
looks like this:
#pragma once
#include <tuple>
#include <type_traits>
#include <concepts>
#include <string_view>
template<typename Allocator, typename ... Views>
requires (sizeof ...(Views) >= 1) && (std::same_as<Views,
std::basic_string_view<typename Views::value_type, typename
Views::traits_type>> && ...)
auto sv_concat( Views ... svs )
{
using namespace std;
using sv_type = tuple_element_t<0, tuple<Views ...>>;
using char_type = sv_type::value_type;
using traits_type = sv_type::traits_type;
basic_string<char_type, traits_type, Allocator> str;
str.reserve( (svs.length() + ...) );
((str += svs), ...);
return str;
}
The only problem with that is that all parameters must be string_views
and can't be sth. which is convertible to a string_view.
string_views to a string. The problem with that that variadic functions
only work with generic types. So I can't write sth. like:
#include <string_view>
#include <string>
using namespace std;
template<typename Allocator, typename Char, typename Traits>
auto sv_concat( basic_string_view<Char, Traits> svs ... )
{
basic_string<Char, Traits, Allocator> str;
str.reserve( (svs.length() + ...) );
((str += svs), ...);
return str;
}
So I did this genrically and I constrained the generic types to
actually be string_views. I made some header out of that which
looks like this:
#pragma once
#include <tuple>
#include <type_traits>
#include <concepts>
#include <string_view>
template<typename Allocator, typename ... Views>
requires (sizeof ...(Views) >= 1) && (std::same_as<Views,
std::basic_string_view<typename Views::value_type, typename
Views::traits_type>> && ...)
auto sv_concat( Views ... svs )
{
using namespace std;
using sv_type = tuple_element_t<0, tuple<Views ...>>;
using char_type = sv_type::value_type;
using traits_type = sv_type::traits_type;
basic_string<char_type, traits_type, Allocator> str;
str.reserve( (svs.length() + ...) );
((str += svs), ...);
return str;
}
The only problem with that is that all parameters must be string_views
and can't be sth. which is convertible to a string_view.