As of C++20 string_view
has remove_prefix
but it is "wrong"(wrong for my usecase) thing.
It takes as an argument number of chars, instead of a prefix(string like thing).
I have this code, but I wonder if there is some nicer way to do what I want(note that my code cares about if prefix was removed so I return boolean):
static bool Consume(std::string_view& view, const std::string_view prefix)
{
if (view.starts_with(prefix))
{
view.remove_prefix(prefix.size());
return true;
}
return false;
}
note: I know I could return optional<string_view>
instead of bool + out arg, but that is a different style discussion, I mostly care about having something like nonexistant
bool /*prefix removed*/string_view::remove_prefix(string_view prefix);
note2: tagged this C++17 because that is when string_view
"arrived", I am fine with any C++20 alternatives.
I mostly care about having something like nonexistant
bool /*prefix removed*/string_view::remove_prefix(string_view prefix);
Indeed, such function is not in standard library. But you've now written such function, and your function is thus a nicer way to do something like what you want.
If you're open for a different design, I would suggest following alternatives:
constexpr std::string_view
remove_prefix(std::string_view sv, std::string_view prefix) noexcept
{
return sv.starts_with(prefix)
? sv.substr(prefix.size())
: sv;
}
// usage
string_view no_prefix = remove_prefix(view, prefix);
bool was_removed = no_prefix.size() != view.size();
Or return a class:
struct modify_result {
std::string_view result;
bool modified;
};
constexpr modify_result
remove_prefix(std::string_view sv, std::string_view prefix) noexcept
{
return sv.starts_with(prefix)
? modify_result{sv.substr(prefix.size()), true}
: modify_result{sv, false};
}
// usage
auto [no_prefix, was_removed] = remove_prefix(view, prefix);
I'm not saying these are better for your use case. These are just alternative solutions which may apply to different use cases.