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
31 changes: 22 additions & 9 deletions module/common/include/oops/str.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <array>
#include <cstddef>
#include <limits>
#include <sstream>
#include <string>
#include <string_view>
Expand All @@ -21,6 +23,19 @@ constexpr bool IsSpace(char c) noexcept {
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; }

namespace detail {
constexpr auto CHAR_MAP = [] {
constexpr std::size_t n{std::numeric_limits<unsigned char>::max() + 1};
std::array<char, n> res{};
for (std::size_t i{0}; i < n; ++i) {
res[i] = static_cast<char>(i);
}
return res;
}();
} // namespace detail

constexpr std::string_view ToSv(char ch) noexcept { return {&detail::CHAR_MAP[static_cast<unsigned char>(ch)], 1}; }

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

Expand Down Expand Up @@ -49,17 +64,16 @@ class SplitView {

bool operator==(const Iterator &other) const {
// 短路和迭代器的比较
if ((s_.data() == nullptr) ^ (other.s_.data() == nullptr)) {
if ((token_.data() == nullptr) ^ (other.token_.data() == nullptr)) {
return false; // 一个迭代器是尾迭代器,另一个不是
}
if (s_.data() == nullptr) {
if (token_.data() == nullptr) {
return true; // 均是尾迭代器
}
// 非尾迭代器的严格匹配
return (s_.data() == other.s_.data()) && (s_.size() == other.s_.size()) &&
(token_.data() == other.token_.data()) && (token_.size() == other.token_.size()) &&
(delim_ == other.delim_) && (any_of_delims_ == other.any_of_delims_) &&
(skip_empty_ == other.skip_empty_);
return (token_.data() == other.token_.data()) && (token_.size() == other.token_.size()) &&
(s_.data() == other.s_.data()) && (s_.size() == other.s_.size()) && (delim_ == other.delim_) &&
(any_of_delims_ == other.any_of_delims_) && (skip_empty_ == other.skip_empty_);
}
bool operator!=(const Iterator &other) const { return !operator==(other); }

Expand All @@ -79,8 +93,8 @@ class SplitView {
using const_iterator = Iterator;
using iterator = Iterator;

SplitView(std::string_view s) : s_{s}, delim_{SPACE}, any_of_delims_{true}, skip_empty_{true} {}
SplitView(std::string_view s, char delim) : s_{s}, delim_(&c_, 1), c_{delim} {}
explicit SplitView(std::string_view s) : s_{s}, delim_{SPACE}, any_of_delims_{true}, skip_empty_{true} {}
SplitView(std::string_view s, char delim) : s_{s}, delim_{ToSv(delim)} {}
SplitView(std::string_view s, std::string_view delim) : s_{s}, delim_{delim} {}

Iterator begin() const { return Iterator(s_, delim_, any_of_delims_, skip_empty_); }
Expand Down Expand Up @@ -114,7 +128,6 @@ class SplitView {
const std::string_view delim_;
bool any_of_delims_{};
bool skip_empty_{};
const char c_{}; // 支持单字符delim
};

inline SplitView Split(std::string_view s) { return SplitView(s); }
Expand Down
13 changes: 7 additions & 6 deletions module/common/include/oops/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,14 @@ class RangeView {
T step_{1};
};

template <typename T, typename Stop>
template <typename T, typename Stop, std::enable_if_t<!std::is_integral_v<Stop>, int> = 0>
constexpr auto Range(T start, Stop stop, T step = 1) {
if constexpr (std::is_integral_v<Stop>) {
return RangeView<T>(start, stop, step);
} else {
return RangeView<T, Stop>(start, stop, step);
}
return RangeView<T, Stop>(start, stop, step);
}

template <typename T>
constexpr auto Range(T start, T stop, T step = 1) {
return RangeView<T>(start, stop, step);
}

template <typename T, typename Stop, std::enable_if_t<!std::is_integral_v<Stop>, int> = 0>
Expand Down
22 changes: 12 additions & 10 deletions module/common/src/str.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,30 @@ std::string SplitBack(const std::string &str, const std::string &delim) {
}

void SplitView::Iterator::NextToken() {
if (s_.data() == nullptr) {
return;
}

do {
if (s_.data() == nullptr) {
token_ = {};
continue;
}

if (s_.empty()) {
token_ = s_;
s_ = {};
return;
continue;
}

std::size_t pos;
std::size_t pos{};
if (any_of_delims_) {
pos = s_.find_first_of(delim_);
} else if (delim_.empty()) {
pos = 1;
} else if (delim_.empty()) { // 特殊分支,空delim的逐字符分割
pos = (s_.size() > 1) ? 1 : std::string_view::npos;
} else {
pos = s_.find(delim_);
}

if (pos == std::string_view::npos) {
token_ = s_;
s_.remove_prefix(s_.size());
s_ = {};
} else {
token_ = s_.substr(0, pos);
if (any_of_delims_) {
Expand All @@ -40,7 +42,7 @@ void SplitView::Iterator::NextToken() {
s_.remove_prefix(pos + delim_.size());
}
}
} while (skip_empty_ && token_.empty() && s_.data() != nullptr);
} while (skip_empty_ && token_.empty() && token_.data() != nullptr);
}

std::string ToUpper(std::string_view s) noexcept {
Expand Down
Loading
Loading