0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-20 03:43:47 +02:00

ircd::string_view: Add noexcept substr(); optimize codegen for split()/rsplit().

This commit is contained in:
Jason Volk 2022-07-14 15:15:28 -07:00
parent 93a7575352
commit 4e29b2429c
2 changed files with 22 additions and 12 deletions

View file

@ -111,6 +111,16 @@ struct ircd::string_view
return data() == reinterpret_cast<const char *>(0x1);
}
// (non-standard) Non-throwing substr() which returns empty rather than std::out_of_range.
// This avoids generating numerous eh handlers/terminations/unwind blocks etc.
using std::string_view::substr;
constexpr auto substr(std::nothrow_t, size_t pos = 0, size_t count = npos) const noexcept
{
pos = std::min(pos, size());
count = std::min(count, size() - pos);
return std::string_view::substr(pos, count);
}
// (non-standard) our faux insert stub
// Tricks boost::spirit into thinking this is mutable string (hint: it's not).
// Instead, the raw[] directive in Qi grammar will use the iterator constructor only.

View file

@ -360,9 +360,9 @@ ircd::rsplit(const string_view &str,
using pair = std::pair<ircd::string_view, ircd::string_view>;
const auto pos(str.rfind(delim));
return pos != string_view::npos?
pair { str.substr(0, pos), str.substr(pos + delim.size()) }:
pair { str, string_view{} };
return pos == string_view::npos?
pair { str, string_view{} }:
pair { str.substr(std::nothrow, 0, pos), str.substr(std::nothrow, pos + delim.size()) };
}
/// Split a string on the last match of delim. Delim not included; no match
@ -374,9 +374,9 @@ ircd::rsplit(const string_view &str,
using pair = std::pair<ircd::string_view, ircd::string_view>;
const auto pos(str.find_last_of(delim));
return pos != string_view::npos?
pair { str.substr(0, pos), str.substr(pos + 1) }:
pair { str, string_view{} };
return pos == string_view::npos?
pair { str, string_view{} }:
pair { str.substr(std::nothrow, 0, pos), str.substr(std::nothrow, pos + 1) };
}
/// Split a string on the first match of delim. Delim not included; no match
@ -388,9 +388,9 @@ ircd::split(const string_view &str,
using pair = std::pair<ircd::string_view, ircd::string_view>;
const auto pos(str.find(delim));
return pos != string_view::npos?
pair { str.substr(0, pos), str.substr(pos + delim.size()) }:
pair { str, string_view{} };
return pos == string_view::npos?
pair { str, string_view{} }:
pair { str.substr(std::nothrow, 0, pos), str.substr(std::nothrow, pos + delim.size()) };
}
/// Split a string on the first match of delim. Delim not included; no match
@ -402,9 +402,9 @@ ircd::split(const string_view &str,
using pair = std::pair<ircd::string_view, ircd::string_view>;
const auto pos(str.find(delim));
return pos != string_view::npos?
pair { str.substr(0, pos), str.substr(pos + 1) }:
pair { str, string_view{} };
return pos == string_view::npos?
pair { str, string_view{} }:
pair { str.substr(std::nothrow, 0, pos), str.substr(std::nothrow, pos + 1) };
}
/// Remove n leading and trailing instances of c from the returned view