|
@@ -21,7 +21,7 @@
|
|
|
//
|
|
|
// ============================================================
|
|
|
//
|
|
|
-// aids — 0.13.0 — std replacement for C++. Designed to aid developers
|
|
|
+// aids — 0.14.0 — std replacement for C++. Designed to aid developers
|
|
|
// to a better programming experience.
|
|
|
//
|
|
|
// https://github.com/rexim/aids
|
|
@@ -30,6 +30,10 @@
|
|
|
//
|
|
|
// ChangeLog (https://semver.org/ is implied)
|
|
|
//
|
|
|
+// 0.14.0 size_t String_View::count_chars(char x) const
|
|
|
+// 0.13.3 Fix control flow in utf8_get_code
|
|
|
+// 0.13.2 Fix magic constant types in utf8_get_code
|
|
|
+// 0.13.1 Remove macros from utf8_get_code implementation
|
|
|
// 0.13.0 void print1(FILE *stream, unsigned int x)
|
|
|
// Maybe<uint32_t> utf8_get_code(String_View view, size_t *size)
|
|
|
// 0.12.1 Fix print1 and sprint1 bug for unsigned long long
|
|
@@ -359,6 +363,17 @@ namespace aids
|
|
|
return prefix.count <= this->count
|
|
|
&& this->subview(0, prefix.count) == prefix;
|
|
|
}
|
|
|
+
|
|
|
+ size_t count_chars(char x) const
|
|
|
+ {
|
|
|
+ size_t result = 0;
|
|
|
+ for (size_t i = 0; i < count; ++i) {
|
|
|
+ if (data[i] == x) {
|
|
|
+ result += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
String_View operator ""_sv(const char *data, size_t count)
|
|
@@ -704,59 +719,56 @@ namespace aids
|
|
|
|
|
|
Maybe<uint32_t> utf8_get_code(String_View view, size_t *size)
|
|
|
{
|
|
|
-#define UTF8_1BYTE_MASK (1 << 7)
|
|
|
-#define UTF8_2BYTES_MASK (1 << 5)
|
|
|
-#define UTF8_3BYTES_MASK (1 << 4)
|
|
|
-#define UTF8_4BYTES_MASK (1 << 3)
|
|
|
-#define UTF8_EXTRA_BYTE_MASK (1 << 6)
|
|
|
- if (view.count >= 1 &&
|
|
|
- (*view.data & UTF8_1BYTE_MASK) == 0)
|
|
|
- {
|
|
|
- *size = 1;
|
|
|
- return {true, static_cast<uint32_t>(*view.data)};
|
|
|
- }
|
|
|
- if (view.count >= 2 &&
|
|
|
- (view.data[0] & UTF8_2BYTES_MASK) == 0 &&
|
|
|
- (view.data[1] & UTF8_EXTRA_BYTE_MASK) == 0)
|
|
|
- {
|
|
|
- *size = 2;
|
|
|
- const auto byte1 = static_cast<uint32_t>((view.data[0] & (UTF8_2BYTES_MASK - 1)) << 6);
|
|
|
- const auto byte2 = static_cast<uint32_t>(view.data[1] & (UTF8_EXTRA_BYTE_MASK - 1));
|
|
|
- return {true, byte1 | byte2};
|
|
|
- }
|
|
|
- if (view.count >= 3 &&
|
|
|
- (view.data[0] & UTF8_3BYTES_MASK) == 0 &&
|
|
|
- (view.data[1] & UTF8_EXTRA_BYTE_MASK) == 0 &&
|
|
|
- (view.data[2] & UTF8_EXTRA_BYTE_MASK) == 0)
|
|
|
- {
|
|
|
- *size = 3;
|
|
|
- const auto byte1 = static_cast<uint32_t>((view.data[0] & (UTF8_3BYTES_MASK - 1)) << (6 * 2));
|
|
|
- const auto byte2 = static_cast<uint32_t>((view.data[1] & (UTF8_EXTRA_BYTE_MASK - 1)) << 6);
|
|
|
- const auto byte3 = static_cast<uint32_t>(view.data[2] & (UTF8_EXTRA_BYTE_MASK - 1));
|
|
|
- return {true, byte1 | byte2 | byte3};
|
|
|
- }
|
|
|
- if (view.count >= 4 &&
|
|
|
- (view.data[0] & UTF8_4BYTES_MASK) == 0 &&
|
|
|
- (view.data[1] & UTF8_EXTRA_BYTE_MASK) == 0 &&
|
|
|
- (view.data[2] & UTF8_EXTRA_BYTE_MASK) == 0 &&
|
|
|
- (view.data[3] & UTF8_EXTRA_BYTE_MASK) == 0)
|
|
|
- {
|
|
|
- *size = 4;
|
|
|
- const auto byte1 = static_cast<uint32_t>((view.data[0] & (UTF8_3BYTES_MASK - 1)) << (6 * 3));
|
|
|
- const auto byte2 = static_cast<uint32_t>((view.data[1] & (UTF8_EXTRA_BYTE_MASK - 1)) << (6 * 2));
|
|
|
- const auto byte3 = static_cast<uint32_t>((view.data[2] & (UTF8_EXTRA_BYTE_MASK - 1)) << 6);
|
|
|
- const auto byte4 = static_cast<uint32_t>(view.data[3] & (UTF8_EXTRA_BYTE_MASK - 1));
|
|
|
- return {true, byte1 | byte2 | byte3 | byte4};
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return {};
|
|
|
- }
|
|
|
-#undef UTF8_1BYTE_MASK
|
|
|
-#undef UTF8_2BYTES_MASK
|
|
|
-#undef UTF8_3BYTES_MASK
|
|
|
-#undef UTF8_4BYTES_MASK
|
|
|
-#undef UTF8_EXTRA_BYTE_MASK
|
|
|
+ const uint8_t UTF8_1BYTE_MASK = 1 << 7;
|
|
|
+ const uint8_t UTF8_2BYTES_MASK = 1 << 5;
|
|
|
+ const uint8_t UTF8_3BYTES_MASK = 1 << 4;
|
|
|
+ const uint8_t UTF8_4BYTES_MASK = 1 << 3;
|
|
|
+ const uint8_t UTF8_EXTRA_BYTE_MASK = 1 << 6;
|
|
|
+
|
|
|
+ if (view.count >= 1 &&
|
|
|
+ (*view.data & UTF8_1BYTE_MASK) == 0)
|
|
|
+ {
|
|
|
+ *size = 1;
|
|
|
+ return {true, static_cast<uint32_t>(*view.data)};
|
|
|
+ }
|
|
|
+
|
|
|
+ if (view.count >= 2 &&
|
|
|
+ (view.data[0] & UTF8_2BYTES_MASK) == 0 &&
|
|
|
+ (view.data[1] & UTF8_EXTRA_BYTE_MASK) == 0)
|
|
|
+ {
|
|
|
+ *size = 2;
|
|
|
+ const auto byte1 = static_cast<uint32_t>((view.data[0] & (UTF8_2BYTES_MASK - 1)) << 6);
|
|
|
+ const auto byte2 = static_cast<uint32_t>(view.data[1] & (UTF8_EXTRA_BYTE_MASK - 1));
|
|
|
+ return {true, byte1 | byte2};
|
|
|
+ }
|
|
|
+
|
|
|
+ if (view.count >= 3 &&
|
|
|
+ (view.data[0] & UTF8_3BYTES_MASK) == 0 &&
|
|
|
+ (view.data[1] & UTF8_EXTRA_BYTE_MASK) == 0 &&
|
|
|
+ (view.data[2] & UTF8_EXTRA_BYTE_MASK) == 0)
|
|
|
+ {
|
|
|
+ *size = 3;
|
|
|
+ const auto byte1 = static_cast<uint32_t>((view.data[0] & (UTF8_3BYTES_MASK - 1)) << (6 * 2));
|
|
|
+ const auto byte2 = static_cast<uint32_t>((view.data[1] & (UTF8_EXTRA_BYTE_MASK - 1)) << 6);
|
|
|
+ const auto byte3 = static_cast<uint32_t>(view.data[2] & (UTF8_EXTRA_BYTE_MASK - 1));
|
|
|
+ return {true, byte1 | byte2 | byte3};
|
|
|
+ }
|
|
|
+
|
|
|
+ if (view.count >= 4 &&
|
|
|
+ (view.data[0] & UTF8_4BYTES_MASK) == 0 &&
|
|
|
+ (view.data[1] & UTF8_EXTRA_BYTE_MASK) == 0 &&
|
|
|
+ (view.data[2] & UTF8_EXTRA_BYTE_MASK) == 0 &&
|
|
|
+ (view.data[3] & UTF8_EXTRA_BYTE_MASK) == 0)
|
|
|
+ {
|
|
|
+ *size = 4;
|
|
|
+ const auto byte1 = static_cast<uint32_t>((view.data[0] & (UTF8_3BYTES_MASK - 1)) << (6 * 3));
|
|
|
+ const auto byte2 = static_cast<uint32_t>((view.data[1] & (UTF8_EXTRA_BYTE_MASK - 1)) << (6 * 2));
|
|
|
+ const auto byte3 = static_cast<uint32_t>((view.data[2] & (UTF8_EXTRA_BYTE_MASK - 1)) << 6);
|
|
|
+ const auto byte4 = static_cast<uint32_t>(view.data[3] & (UTF8_EXTRA_BYTE_MASK - 1));
|
|
|
+ return {true, byte1 | byte2 | byte3 | byte4};
|
|
|
+ }
|
|
|
+
|
|
|
+ return {};
|
|
|
}
|
|
|
}
|
|
|
|