diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 04:48:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 04:48:35 +0000 |
commit | 207df6fc406e81bfeebdff7f404bd242ff3f099f (patch) | |
tree | a1a796b056909dd0a04ffec163db9363a8757808 /src/base/intern_string.hh | |
parent | Releasing progress-linux version 0.11.2-1~progress7.99u1. (diff) | |
download | lnav-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.hh | 144 |
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 |