Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 67 additions & 50 deletions module/common/include/oops/str.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,22 @@

namespace oops {
constexpr std::string_view SPACE{" \t\n\r\v\f"};
std::string Repeat(const std::string &str, std::size_t n);
std::string SplitBack(const std::string &str, const std::string &delim);

// 字符操作
constexpr bool IsUpper(char c) noexcept { return 'A' <= c && c <= 'Z'; }
constexpr bool IsLower(char c) noexcept { return 'a' <= c && c <= 'z'; }
constexpr bool IsAlpha(char c) noexcept { return IsUpper(c) || IsLower(c); }
constexpr bool IsDigit(char c) noexcept { return '0' <= c && c <= '9'; }
constexpr bool IsAlnum(char c) noexcept { return IsAlpha(c) || IsDigit(c); }
constexpr bool IsSpace(char c) noexcept {
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
}

constexpr char ToUpper(char c) noexcept { return IsLower(c) ? (c - 'a' + 'A') : c; }
constexpr char ToLower(char c) noexcept { return IsUpper(c) ? (c - 'A' + 'a') : c; }

// 字符串读操作
std::string SplitBack(const std::string &str, const std::string &delim); // SplitView实现逆序迭代器后合并到Split中

class SplitView {
public:
Expand Down Expand Up @@ -73,6 +87,7 @@ class SplitView {
Iterator end() const { return Iterator(); }

std::string_view Front() const { return *begin(); }
bool Empty() const { return begin() == end(); }

SplitView &AnyOfDelims(bool b = true) {
any_of_delims_ = b;
Expand Down Expand Up @@ -106,19 +121,47 @@ inline SplitView Split(std::string_view s) { return SplitView(s); }
inline SplitView Split(std::string_view s, char delim) { return SplitView(s, delim); }
inline SplitView Split(std::string_view s, std::string_view delim) { return SplitView(s, delim); }

constexpr bool IsUpper(char c) noexcept { return 'A' <= c && c <= 'Z'; }
constexpr bool IsLower(char c) noexcept { return 'a' <= c && c <= 'z'; }
constexpr bool IsAlpha(char c) noexcept { return IsUpper(c) || IsLower(c); }
constexpr bool IsDigit(char c) noexcept { return '0' <= c && c <= '9'; }
constexpr bool IsAlnum(char c) noexcept { return IsAlpha(c) || IsDigit(c); }
constexpr bool IsSpace(char c) noexcept {
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
constexpr std::string_view StripLeft(std::string_view s, std::string_view chars = SPACE) {
std::size_t pos{s.find_first_not_of(chars)};
if (pos == std::string_view::npos) {
pos = s.size();
}
s.remove_prefix(pos);
return s;
}

constexpr char ToUpper(char c) noexcept { return IsLower(c) ? (c - 'a' + 'A') : c; }
constexpr char ToLower(char c) noexcept { return IsUpper(c) ? (c - 'A' + 'a') : c; }
constexpr std::string_view StripRight(std::string_view s, std::string_view chars = SPACE) {
std::size_t pos{s.find_last_not_of(chars) + 1};
if (pos == std::string_view::npos) {
pos = s.size();
}
s.remove_suffix(s.size() - pos);
return s;
}

std::string ToLower(std::string_view s) noexcept;
constexpr std::string_view Strip(std::string_view s, std::string_view chars = SPACE) {
return StripLeft(StripRight(s, chars), chars);
}

constexpr bool StartsWith(std::string_view s, std::string_view prefix) {
if (prefix.empty()) {
return true;
}
if (prefix.size() > s.size()) {
return false;
}
return s.substr(0, prefix.size()) == prefix;
}

constexpr bool EndsWith(std::string_view s, std::string_view suffix) {
if (suffix.empty()) {
return true;
}
if (suffix.size() > s.size()) {
return false;
}
return s.substr(s.size() - suffix.size()) == suffix;
}

constexpr bool Equal(std::string_view lhs, std::string_view rhs) noexcept { return lhs == rhs; }

Expand All @@ -137,59 +180,33 @@ constexpr bool Equal(std::string_view lhs, std::string_view rhs, CharEqual &&cha

template <typename CharEqual, typename Filter>
constexpr bool Equal(std::string_view lhs, std::string_view rhs, CharEqual &&char_equal, Filter &&filter) noexcept {
for (std::size_t i{0}, j{0}; true; ++i, ++j) {
while (i < lhs.size() && !filter(lhs[i])) {
for (std::size_t i{0}, j{0};; ++i, ++j) {
while ((i < lhs.size()) && (!filter(lhs[i]))) {
++i;
}
while (j < rhs.size() && !filter(rhs[j])) {
while ((j < rhs.size()) && (!filter(rhs[j]))) {
++j;
}
if (i == lhs.size() && j == rhs.size()) {
return true;
if ((i == lhs.size()) ^ (j == rhs.size())) {
return false; // 一个查找到末尾,另一个没有
}
if (i == lhs.size() || j == rhs.size()) {
return false;
if (i == lhs.size()) {
return true;
}
if (!char_equal(lhs[i], rhs[j])) {
return false;
}
}
}

constexpr bool StartsWith(std::string_view s, std::string_view prefix) {
if (prefix.empty()) {
return true;
}
if (prefix.size() > s.size()) {
return false;
}
return s.substr(0, prefix.size()) == prefix;
}

constexpr bool EndsWith(std::string_view s, std::string_view suffix) {
if (suffix.empty()) {
return true;
}
if (suffix.size() > s.size()) {
return false;
}
return s.substr(s.size() - suffix.size()) == suffix;
}

constexpr std::string_view Strip(std::string_view s, std::string_view chars = SPACE) {
if (s.empty()) {
return s;
}
std::size_t pos{s.find_first_not_of(chars)};
if (pos == std::string_view::npos) {
return {};
}
return s.substr(pos, s.find_last_not_of(chars) - pos + 1);
}
// 字符串写操作
std::string ToLower(std::string_view s) noexcept;
std::string ToUpper(std::string_view s) noexcept;

std::string Repeat(const std::string &str, std::size_t n);
std::string Elide(std::string_view s, std::size_t n);

// 后续替换成lexcial_cast
// 后续使用lexcial_cast替代
template <typename T>
::std::string ToStr(const T &t) {
::std::ostringstream oss;
Expand Down
90 changes: 44 additions & 46 deletions module/common/include/oops/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,50 @@ class RangeView {
static_assert(std::is_same_v<T, Stop> || !std::is_integral_v<Stop>);

public:
class Iterator;
class Iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = const T *;
using reference = const T &;

constexpr explicit Iterator(T t, T step) : t_{t}, step_{step} {}
constexpr T operator*() const noexcept { return t_; }

constexpr Iterator &operator++() noexcept {
auto res{AddOverflow(t_, step_)};
t_ = res.value;
overflow_ = res.overflow;
return *this;
}

constexpr Iterator operator++(int) noexcept {
auto iter{*this};
++(*this);
return iter;
}

bool Overflow() const { return overflow_; }
T Step() const { return step_; }

constexpr bool operator==(Stop stop) const {
if constexpr (std::is_integral_v<Stop>) {
if (step_ > 0) {
return stop <= t_;
}
return stop >= t_;
} else {
return stop == (*this);
}
}
constexpr bool operator!=(Stop stop) const { return !operator==(stop); }

private:
T t_, step_;
bool overflow_{false};
};

constexpr RangeView(Stop stop) : stop_{stop} {}
constexpr RangeView(T start, Stop stop, T step = 1) : start_{start}, stop_{stop}, step_{step} {
if (step == 0) {
Expand All @@ -97,51 +140,6 @@ class RangeView {
T step_{1};
};

template <typename T, typename Stop>
class RangeView<T, Stop>::Iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = const T *;
using reference = const T &;

constexpr explicit Iterator(T t, T step) : t_{t}, step_{step} {}
constexpr T operator*() const noexcept { return t_; }

constexpr Iterator &operator++() noexcept {
auto res{AddOverflow(t_, step_)};
t_ = res.value;
overflow_ = res.overflow;
return *this;
}

constexpr Iterator operator++(int) noexcept {
auto iter{*this};
++(*this);
return iter;
}

bool Overflow() const { return overflow_; }
T Step() const { return step_; }

constexpr bool operator==(Stop stop) const {
if constexpr (std::is_integral_v<Stop>) {
if (step_ > 0) {
return stop <= t_;
}
return stop >= t_;
} else {
return stop == (*this);
}
}
constexpr bool operator!=(Stop stop) const { return !operator==(stop); }

protected:
T t_, step_;
bool overflow_{false};
};

template <typename T, typename Stop>
constexpr auto Range(T start, Stop stop, T step = 1) {
if constexpr (std::is_integral_v<Stop>) {
Expand Down
34 changes: 20 additions & 14 deletions module/common/src/str.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
#include "oops/str.h"

#include <algorithm>
#include <cassert>
#include <cstring>

namespace oops {
std::string Repeat(const std::string &str, std::size_t n) {
if (n == 0 || str.empty()) {
return {};
}
std::string res;
res.reserve(n * str.size());
for (std::size_t i{0}; i < n; ++i) {
res.append(str);
}
return res;
}

std::string SplitBack(const std::string &str, const std::string &delim) {
return str.substr(str.rfind(delim) + delim.size());
}
Expand Down Expand Up @@ -54,11 +43,28 @@ void SplitView::Iterator::NextToken() {
} while (skip_empty_ && token_.empty() && s_.data() != nullptr);
}

std::string ToUpper(std::string_view s) noexcept {
std::string res;
res.reserve(s.size());
std::transform(s.begin(), s.end(), std::back_inserter(res), (char (*)(char)){ToUpper});
return res;
}

std::string ToLower(std::string_view s) noexcept {
std::string res;
res.reserve(s.size());
for (char ch : s) {
res.push_back(ToLower(ch));
std::transform(s.begin(), s.end(), std::back_inserter(res), (char (*)(char)){ToLower});
return res;
}

std::string Repeat(const std::string &str, std::size_t n) {
if (n == 0 || str.empty()) {
return {};
}
std::string res;
res.reserve(n * str.size());
for (std::size_t i{0}; i < n; ++i) {
res.append(str);
}
return res;
}
Expand Down
14 changes: 7 additions & 7 deletions module/profiling/src/system_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ std::string FormatField(const Storage<R, P> &storage, std::string_view ctx = "{}

// proc::smaps::VmaExt::VmFlags特化
struct VmFlagsEntry {
using VmFlags = proc::smaps::VmaExt::VmFlags;
std::string_view key;
void (*set)(proc::smaps::VmaExt::VmFlags &);
bool (*get)(const proc::smaps::VmaExt::VmFlags &);
void (*set)(VmFlags &);
bool (*get)(const VmFlags &);
};

#define ENTRY(flag) \
{ \
#flag, [](proc::smaps::VmaExt::VmFlags &f) { f.flag = true; }, \
[](const proc::smaps::VmaExt::VmFlags &f) { return f.flag; } \
#define ENTRY(f) \
{ \
#f, [](auto &f) { f.rd = true; }, [](auto &f) { return f.rd; } \
}
constexpr VmFlagsEntry VM_FLAGS_TABLE[]{ENTRY(rd), ENTRY(wr), ENTRY(ex), ENTRY(sh), ENTRY(mr), ENTRY(mw), ENTRY(me),
ENTRY(ms), ENTRY(gd), ENTRY(pf), ENTRY(dw), ENTRY(lo), ENTRY(io), ENTRY(sr),
Expand All @@ -106,7 +106,7 @@ bool ParseField(std::string_view s, proc::smaps::VmaExt::VmFlags &vm_flags, std:
template <>
std::string FormatField(const proc::smaps::VmaExt::VmFlags &vm_flags, std::string_view) {
std::string s;
s.reserve(64);
s.reserve(64); // one cache line
for (const auto &item : VM_FLAGS_TABLE) {
if (item.get(vm_flags)) {
s += item.key;
Expand Down
4 changes: 2 additions & 2 deletions module/profiling/tool/monitor/monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,20 +261,20 @@ void SearchValidInput() {

template <typename T>
auto ParseValueAfterPrefix(std::string_view s, std::string_view prefix, T &value) noexcept {
s = oops::Strip(s);
struct {
explicit operator bool() const noexcept { return matched && parsed; }
std::string_view remain;
bool matched{false};
bool parsed{false};
} res;

s = oops::Strip(s);
auto pos{s.find(prefix)};
if (pos == std::string_view::npos) {
return res;
}
s.remove_prefix(pos + prefix.size());
s = oops::Strip(s); // 使用StripLeft优化
s = oops::StripLeft(s);
res.matched = true;
res.remain = s;

Expand Down
Loading