I'd like to implement a non-copy data trim_left function, but would like to not allow it to accept temporary parameters to make the returned string_view is valid (the data is still alive). I started accepting string_view as parameter, but I cannot get the way how to guarantee the data is valid.
So I make this:
template<typename T>
std::string_view trim_left( const T& data, std::string_view trimChars )
{
std::string_view sv{data};
sv.remove_prefix( std::min(sv.find_first_not_of(trimChars), sv.size()));
return sv;
}
template<typename T, std::enable_if_t< !std::is_same<std::decay_t<T>,std::string_view>::value , int > = 0>
std::string_view trim_left( const T&& data, std::string_view trimChars ) = delete;
My idea with the second deleted template is to disable the use of temporary object as parameters and guarantee the returned string_view is valid.
I expect that this is valid:
auto sv1 = trim_left("ABCHello" , "ABC");
string data = "ABCHello";
auto sv2 = trim_left( data, "ABC");
but not this...
string fee( return "ABCHello"; );
auto sv3 = trim_left( fee(), "ABC");
Is this the proper way to do it? Is it possible to do this by setting a enable_if parameter on the first template and not use the second one?
Test implementation:https://wandbox.org/permlink/7q3cLGbGrX9b6q5S
Thanks!!
I find out this second implementation:
template<typename T, std::enable_if_t< std::is_same<T, std::string_view>::value || !std::is_rvalue_reference_v<T&&>, int > = 0 >
std::string_view trim_left( T&& data, std::string_view trimChars )
{
std::string_view sv{std::forward<T>(data)};
sv.remove_prefix( std::min(sv.find_first_not_of(trimChars), sv.size()));
return sv;
}
Test case: https://wandbox.org/permlink/ZOaO4NDI28yQHXy9
I think is simple than the first one, and also works with the tests. Seems it's what I was looking for.