summaryrefslogtreecommitdiffstats
path: root/src/base/intern_string.hh
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 04:48:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 04:48:35 +0000
commit207df6fc406e81bfeebdff7f404bd242ff3f099f (patch)
treea1a796b056909dd0a04ffec163db9363a8757808 /src/base/intern_string.hh
parentReleasing progress-linux version 0.11.2-1~progress7.99u1. (diff)
downloadlnav-207df6fc406e81bfeebdff7f404bd242ff3f099f.tar.xz
lnav-207df6fc406e81bfeebdff7f404bd242ff3f099f.zip
Merging upstream version 0.12.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/base/intern_string.hh')
-rw-r--r--src/base/intern_string.hh144
1 files changed, 103 insertions, 41 deletions
diff --git a/src/base/intern_string.hh b/src/base/intern_string.hh
index 4ae40da..f77dc49 100644
--- a/src/base/intern_string.hh
+++ b/src/base/intern_string.hh
@@ -33,7 +33,6 @@
#define intern_string_hh
#include <ostream>
-#include <string>
#include <vector>
#include <assert.h>
@@ -42,9 +41,9 @@
#include "fmt/format.h"
#include "optional.hpp"
+#include "result.h"
#include "scn/util/string_view.h"
#include "strnatcmp.h"
-#include "ww898/cp_utf8.hpp"
struct string_fragment {
using iterator = const char*;
@@ -143,6 +142,8 @@ struct string_fragment {
Result<ssize_t, const char*> utf8_length() const;
+ size_t column_width() const;
+
const char* data() const { return &this->sf_string[this->sf_begin]; }
const unsigned char* udata() const
@@ -157,16 +158,7 @@ struct string_fragment {
char front() const { return this->sf_string[this->sf_begin]; }
- uint32_t front_codepoint() const
- {
- size_t index = 0;
- try {
- return ww898::utf::utf8::read(
- [this, &index]() { return this->data()[index++]; });
- } catch (const std::runtime_error& e) {
- return this->data()[0];
- }
- }
+ uint32_t front_codepoint() const;
char back() const { return this->sf_string[this->sf_end - 1]; }
@@ -183,25 +175,10 @@ struct string_fragment {
bool empty() const { return !this->is_valid() || length() == 0; }
- Result<ssize_t, const char*> codepoint_to_byte_index(ssize_t cp_index) const
- {
- ssize_t retval = 0;
-
- while (cp_index > 0) {
- if (retval >= this->length()) {
- return Err("index is beyond the end of the string");
- }
- auto ch_len = TRY(ww898::utf::utf8::char_size([this, retval]() {
- return std::make_pair(this->data()[retval],
- this->length() - retval - 1);
- }));
-
- retval += ch_len;
- cp_index -= 1;
- }
+ Result<ssize_t, const char*> codepoint_to_byte_index(
+ ssize_t cp_index) const;
- return Ok(retval);
- }
+ string_fragment sub_cell_range(int cell_start, int cell_end) const;
const char& operator[](int index) const
{
@@ -228,6 +205,22 @@ struct string_fragment {
return memcmp(this->data(), sf.data(), sf.length()) == 0;
}
+ bool operator!=(const string_fragment& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ bool operator<(const string_fragment& rhs) const
+ {
+ auto rc = strncmp(
+ this->data(), rhs.data(), std::min(this->length(), rhs.length()));
+ if (rc < 0 || (rc == 0 && this->length() < rhs.length())) {
+ return true;
+ }
+
+ return false;
+ }
+
bool iequal(const string_fragment& sf) const
{
if (this->length() != sf.length()) {
@@ -290,6 +283,12 @@ struct string_fragment {
this->sf_string, this->sf_begin + begin, this->sf_begin + end};
}
+ bool contains(const string_fragment& sf) const
+ {
+ return this->sf_string == sf.sf_string && this->sf_begin <= sf.sf_begin
+ && sf.sf_end <= this->sf_end;
+ }
+
size_t count(char ch) const
{
size_t retval = 0;
@@ -315,7 +314,9 @@ struct string_fragment {
}
template<typename P>
- string_fragment find_left_boundary(size_t start, P&& predicate) const
+ string_fragment find_left_boundary(size_t start,
+ P&& predicate,
+ size_t count = 1) const
{
assert((int) start <= this->length());
@@ -324,25 +325,33 @@ struct string_fragment {
}
while (start > 0) {
if (predicate(this->data()[start])) {
- start += 1;
- break;
+ count -= 1;
+ if (count == 0) {
+ start += 1;
+ break;
+ }
}
start -= 1;
}
return string_fragment{
this->sf_string,
- (int) start,
+ this->sf_begin + (int) start,
this->sf_end,
};
}
template<typename P>
- string_fragment find_right_boundary(size_t start, P&& predicate) const
+ string_fragment find_right_boundary(size_t start,
+ P&& predicate,
+ size_t count = 1) const
{
while ((int) start < this->length()) {
if (predicate(this->data()[start])) {
- break;
+ count -= 1;
+ if (count == 0) {
+ break;
+ }
}
start += 1;
}
@@ -355,10 +364,14 @@ struct string_fragment {
}
template<typename P>
- string_fragment find_boundaries_around(size_t start, P&& predicate) const
+ string_fragment find_boundaries_around(size_t start,
+ P&& predicate,
+ size_t count = 1) const
{
- return this->template find_left_boundary(start, predicate)
- .find_right_boundary(0, predicate);
+ auto left = this->template find_left_boundary(start, predicate, count);
+
+ return left.find_right_boundary(
+ start - left.sf_begin, predicate, count);
}
nonstd::optional<std::pair<uint32_t, string_fragment>> consume_codepoint()
@@ -446,8 +459,10 @@ struct string_fragment {
});
}
+ using split_when_result = std::pair<string_fragment, string_fragment>;
+
template<typename P>
- split_result split_when(P&& predicate) const
+ split_when_result split_when(P&& predicate) const
{
int consumed = 0;
while (consumed < this->length()) {
@@ -458,7 +473,33 @@ struct string_fragment {
consumed += 1;
}
- if (consumed == 0) {
+ return std::make_pair(
+ string_fragment{
+ this->sf_string,
+ this->sf_begin,
+ this->sf_begin + consumed,
+ },
+ string_fragment{
+ this->sf_string,
+ this->sf_begin + consumed
+ + ((consumed == this->length()) ? 0 : 1),
+ this->sf_end,
+ });
+ }
+
+ template<typename P>
+ split_result split_pair(P&& predicate) const
+ {
+ int consumed = 0;
+ while (consumed < this->length()) {
+ if (predicate(this->data()[consumed])) {
+ break;
+ }
+
+ consumed += 1;
+ }
+
+ if (consumed == this->length()) {
return nonstd::nullopt;
}
@@ -517,6 +558,8 @@ struct string_fragment {
return {this->data(), (size_t) this->length()};
}
+ std::string to_unquoted_string() const;
+
void clear()
{
this->sf_begin = 0;
@@ -823,6 +866,12 @@ operator==(const string_fragment& left, const intern_string_t& right)
&& (memcmp(left.data(), right.get(), left.length()) == 0);
}
+inline string_fragment
+operator"" _frag(const char* str, std::size_t len)
+{
+ return string_fragment::from_byte_range(str, 0, len);
+}
+
namespace std {
inline string
to_string(const string_fragment& s)
@@ -855,6 +904,12 @@ to_string_fragment(const std::string& s)
return string_fragment(s.c_str(), 0, s.length());
}
+inline string_fragment
+to_string_fragment(const scn::string_view& sv)
+{
+ return string_fragment::from_bytes(sv.data(), sv.length());
+}
+
struct frag_hasher {
size_t operator()(const string_fragment& sf) const
{
@@ -862,4 +917,11 @@ struct frag_hasher {
}
};
+struct intern_hasher {
+ size_t operator()(const intern_string_t& is) const
+ {
+ return hash_str(is.c_str(), is.size());
+ }
+};
+
#endif