Skip to content
Closed
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
16 changes: 8 additions & 8 deletions ZACLib/ZACLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace ZACLib {
if (from.empty()) return;
if (from.size() > max_rule_len) max_rule_len = from.size();
int node = 0;
for (const char i : from) {
for (const ZAC_CHAR i : from) {
const auto c = static_cast<unsigned char>(i);
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions)
Expand All @@ -32,7 +32,7 @@ namespace ZACLib {
if (from.size() > trie[node].match_len) {
trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions)
trie[node].match_len = from.size();
outputs.emplace_back(to.data(), to.size());
outputs.emplace_back(reinterpret_cast<const char*>(to.data()), to.size());
}
}

Expand Down Expand Up @@ -82,7 +82,7 @@ namespace ZACLib {

if (input.empty()) return result;
if (max_rule_len == 0) {
result.append(input.data(), input.size());
result.append(reinterpret_cast<const char*>(input.data()), input.size());
return result;
}

Expand Down Expand Up @@ -130,15 +130,15 @@ namespace ZACLib {
continue;
}

result.append(input.data() + last_pos, cursor - last_pos);
result.append(reinterpret_cast<const char*>(input.data() + last_pos), cursor - last_pos);
result.append(outputs[best_output]);
cursor += best_len;
last_pos = cursor;
}
};

for (size_t i = 0; i < input.size(); ++i) {
const unsigned char c = input[i];
const auto c = static_cast<unsigned char>(input[i]);
state = trie[state].next[c];

if (trie[state].output_id != invalid_output) {
Expand All @@ -154,7 +154,7 @@ namespace ZACLib {
emit_until(input.size());

if (last_pos < input.size()) {
result.append(input.data() + last_pos, input.size() - last_pos);
result.append(reinterpret_cast<const char*>(input.data() + last_pos), input.size() - last_pos);
}

return result;
Expand All @@ -168,7 +168,7 @@ namespace ZACLib {
void Search::AddRule(const ZAC_SV& from) {
if (from.empty()) return;
int node = 0;
for (const char i : from) {
for (const ZAC_CHAR i : from) {
const auto c = static_cast<unsigned char>(i);
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions)
Expand All @@ -180,7 +180,7 @@ namespace ZACLib {
if (from.size() > trie[node].match_len) {
trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions)
trie[node].match_len = from.size();
outputs.emplace_back(from.data(), from.size());
outputs.emplace_back(reinterpret_cast<const char*>(from.data()), from.size());
}
}

Expand Down
59 changes: 47 additions & 12 deletions ZACLib/ZACLib_Types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,63 @@
#include <array>
#include <limits>

#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
using ZAC_CHAR = unsigned char;
#else
using ZAC_CHAR = char;
#endif


namespace ZACLib {
#if __cplusplus >= 201703L
using ZAC_SV = std::string_view;
class ZAC_SV : public std::basic_string_view<ZAC_CHAR> {
public:
using std::basic_string_view<ZAC_CHAR>::basic_string_view;
ZAC_SV() = default;

// ReSharper disable once CppRedundantCastExpression
ZAC_SV(const std::string& s) noexcept
: std::basic_string_view<ZAC_CHAR>(reinterpret_cast<const ZAC_CHAR*>(s.data()), s.size()) {}

#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
ZAC_SV(const char* s, const size_t n)
: std::basic_string_view<ZAC_CHAR>(reinterpret_cast<const ZAC_CHAR*>(s), n) {}

ZAC_SV(const char* s)
: std::basic_string_view<ZAC_CHAR>(
reinterpret_cast<const ZAC_CHAR*>(s),
s ? std::char_traits<char>::length(s) : 0) {}
#endif
Comment on lines +37 to +45
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The preprocessor condition defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__) is repeated multiple times in this file. To improve maintainability and avoid potential inconsistencies, consider defining a single macro for this check where ZAC_CHAR is defined, and reusing it.

For example:

// At file scope
#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
#define ZAC_CHAR_IS_UNSIGNED 1
#else
#define ZAC_CHAR_IS_UNSIGNED 0
#endif

// ... then later
#if ZAC_CHAR_IS_UNSIGNED
// ...
#endif

};
#else
class ZAC_SV {
const char* m_data;
const ZAC_CHAR* m_data;
const size_t m_size;
public:
ZAC_SV() : m_data(nullptr),
m_size(0) {}

ZAC_SV(const char* d, const size_t s) : m_data(d),
ZAC_SV(const ZAC_CHAR* d, const size_t s) : m_data(d),
m_size(s) {}

ZAC_SV(const std::string& s) : m_data(s.c_str()),
#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
ZAC_SV(const char* d, const size_t s) : m_data(reinterpret_cast<const ZAC_CHAR*>(d)),
m_size(s) {}
#endif

// ReSharper disable once CppRedundantCastExpression
ZAC_SV(const std::string& s) : m_data(reinterpret_cast<const ZAC_CHAR*>(s.c_str())),
m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造
Comment on lines +64 to 65
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with std::string_view and the C++17 version of ZAC_SV, several constructors in the pre-C++17 implementation should be marked noexcept as they don't perform any operations that can throw. This includes this constructor, and the ones at lines 55 and 59.

Additionally, for consistency with the C++17 version and modern C++ practice, consider using s.data() instead of s.c_str() in this constructor.

        ZAC_SV(const std::string& s) noexcept : m_data(reinterpret_cast<const ZAC_CHAR*>(s.data())),
                                       m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造


ZAC_SV(const char* d) : m_data(d),
m_size(d ? std::strlen(d) : 0) {} // 模仿std::string_view,不禁止隐式构造
ZAC_SV(const ZAC_CHAR* d) : m_data(d),
m_size(d ? std::strlen(reinterpret_cast<const char*>(d)) : 0) {} // 模仿std::string_view,不禁止隐式构造

#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
ZAC_SV(const char* d) : m_data(reinterpret_cast<const ZAC_CHAR*>(d)),
m_size(d ? std::strlen(d) : 0) {}
#endif

const char* data() const noexcept {
const ZAC_CHAR* data() const noexcept {
return m_data;
}

Expand All @@ -49,12 +84,12 @@ namespace ZACLib {
return m_size == 0;
}

const char* begin() const { return m_data; }
const char* end() const { return m_data + m_size; }
const char* cbegin() const { return m_data; }
const char* cend() const { return m_data + m_size; }
const ZAC_CHAR* begin() const { return m_data; }
const ZAC_CHAR* end() const { return m_data + m_size; }
const ZAC_CHAR* cbegin() const { return m_data; }
const ZAC_CHAR* cend() const { return m_data + m_size; }

const char& operator[](const size_t i) const { return m_data[i]; }
const ZAC_CHAR& operator[](const size_t i) const { return m_data[i]; }
};
#endif

Expand Down
75 changes: 55 additions & 20 deletions ZACLib/ZACLib_single.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,64 @@
#include <array>
#include <limits>

#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
using ZAC_CHAR = unsigned char;
#else
using ZAC_CHAR = char;
#endif


namespace ZACLib {
#if __cplusplus >= 201703L
using ZAC_SV = std::string_view;
class ZAC_SV : public std::basic_string_view<ZAC_CHAR> {
public:
using std::basic_string_view<ZAC_CHAR>::basic_string_view;
ZAC_SV() = default;

// ReSharper disable once CppRedundantCastExpression
ZAC_SV(const std::string& s) noexcept
: std::basic_string_view<ZAC_CHAR>(reinterpret_cast<const ZAC_CHAR*>(s.data()), s.size()) {}

#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
ZAC_SV(const char* s, const size_t n)
: std::basic_string_view<ZAC_CHAR>(reinterpret_cast<const ZAC_CHAR*>(s), n) {}

ZAC_SV(const char* s)
: std::basic_string_view<ZAC_CHAR>(
reinterpret_cast<const ZAC_CHAR*>(s),
s ? std::char_traits<char>::length(s) : 0) {}
#endif
Comment on lines +52 to +60
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The preprocessor condition defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__) is repeated multiple times in this file. To improve maintainability and avoid potential inconsistencies, consider defining a single macro for this check where ZAC_CHAR is defined, and reusing it.

For example:

// At file scope
#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
#define ZAC_CHAR_IS_UNSIGNED 1
#else
#define ZAC_CHAR_IS_UNSIGNED 0
#endif

// ... then later
#if ZAC_CHAR_IS_UNSIGNED
// ...
#endif

};
#else
class ZAC_SV {
const char* m_data;
const ZAC_CHAR* m_data;
const size_t m_size;

public:
ZAC_SV() : m_data(nullptr),
m_size(0) {}

ZAC_SV(const char* d, const size_t s) : m_data(d),
ZAC_SV(const ZAC_CHAR* d, const size_t s) : m_data(d),
m_size(s) {}

#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
ZAC_SV(const char* d, const size_t s) : m_data(reinterpret_cast<const ZAC_CHAR*>(d)),
m_size(s) {}
#endif

ZAC_SV(const std::string& s) : m_data(s.c_str()),
// ReSharper disable once CppRedundantCastExpression
ZAC_SV(const std::string& s) : m_data(reinterpret_cast<const ZAC_CHAR*>(s.c_str())),
m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造
Comment on lines +80 to 81
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with std::string_view and the C++17 version of ZAC_SV, several constructors in the pre-C++17 implementation should be marked noexcept as they don't perform any operations that can throw. This includes this constructor, and the ones at lines 71 and 75.

Additionally, for consistency with the C++17 version and modern C++ practice, consider using s.data() instead of s.c_str() in this constructor.

        ZAC_SV(const std::string& s) noexcept : m_data(reinterpret_cast<const ZAC_CHAR*>(s.data())),
                                       m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造


ZAC_SV(const char* d) : m_data(d),
m_size(d ? std::strlen(d) : 0) {} // 模仿std::string_view,不禁止隐式构造
ZAC_SV(const ZAC_CHAR* d) : m_data(d),
m_size(d ? std::strlen(reinterpret_cast<const char*>(d)) : 0) {} // 模仿std::string_view,不禁止隐式构造

const char* data() const noexcept {
#if defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__)
ZAC_SV(const char* d) : m_data(reinterpret_cast<const ZAC_CHAR*>(d)),
m_size(d ? std::strlen(d) : 0) {}
#endif

const ZAC_CHAR* data() const noexcept {
return m_data;
}

Expand All @@ -65,12 +100,12 @@ namespace ZACLib {
return m_size == 0;
}

const char* begin() const { return m_data; }
const char* end() const { return m_data + m_size; }
const char* cbegin() const { return m_data; }
const char* cend() const { return m_data + m_size; }
const ZAC_CHAR* begin() const { return m_data; }
const ZAC_CHAR* end() const { return m_data + m_size; }
const ZAC_CHAR* cbegin() const { return m_data; }
const ZAC_CHAR* cend() const { return m_data + m_size; }

const char& operator[](const size_t i) const { return m_data[i]; }
const ZAC_CHAR& operator[](const size_t i) const { return m_data[i]; }
};
#endif

Expand Down Expand Up @@ -105,7 +140,7 @@ namespace ZACLib {
if (from.empty()) return;
if (from.size() > max_rule_len) max_rule_len = from.size();
int node = 0;
for (const char i : from) {
for (const ZAC_CHAR i : from) {
const auto c = static_cast<unsigned char>(i);
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions)
Expand All @@ -116,7 +151,7 @@ namespace ZACLib {
if (from.size() > trie[node].match_len) {
trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions)
trie[node].match_len = from.size();
outputs.emplace_back(to.data(), to.size());
outputs.emplace_back(reinterpret_cast<const char*>(to.data()), to.size());
}
}

Expand Down Expand Up @@ -158,7 +193,7 @@ namespace ZACLib {

if (input.empty()) return result;
if (max_rule_len == 0) {
result.append(input.data(), input.size());
result.append(reinterpret_cast<const char*>(input.data()), input.size());
return result;
}

Expand Down Expand Up @@ -206,15 +241,15 @@ namespace ZACLib {
continue;
}

result.append(input.data() + last_pos, cursor - last_pos);
result.append(reinterpret_cast<const char*>(input.data() + last_pos), cursor - last_pos);
result.append(outputs[best_output]);
cursor += best_len;
last_pos = cursor;
}
};

for (size_t i = 0; i < input.size(); ++i) {
const unsigned char c = input[i];
const auto c = static_cast<unsigned char>(input[i]);
state = trie[state].next[c];

if (trie[state].output_id != invalid_output) {
Expand All @@ -230,7 +265,7 @@ namespace ZACLib {
emit_until(input.size());

if (last_pos < input.size()) {
result.append(input.data() + last_pos, input.size() - last_pos);
result.append(reinterpret_cast<const char*>(input.data() + last_pos), input.size() - last_pos);
}

return result;
Expand All @@ -255,7 +290,7 @@ namespace ZACLib {
void AddRule(const ZAC_SV& from) {
if (from.empty()) return;
int node = 0;
for (const char i : from) {
for (const ZAC_CHAR i : from) {
const auto c = static_cast<unsigned char>(i);
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions)
Expand All @@ -266,7 +301,7 @@ namespace ZACLib {
if (from.size() > trie[node].match_len) {
trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions)
trie[node].match_len = from.size();
outputs.emplace_back(from.data(), from.size());
outputs.emplace_back(reinterpret_cast<const char*>(from.data()), from.size());
}
}

Expand Down