NoSenseEtAl
NoSenseEtAl

Reputation: 30028

Best way to remove string prefix from std::string_view?

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.

Upvotes: 2

Views: 2991

Answers (1)

eerorika
eerorika

Reputation: 238351

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.

Upvotes: 5

Related Questions