summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/engine.cpp6
-rw-r--r--core/config/engine.h6
-rw-r--r--core/config/project_settings.cpp6
-rw-r--r--core/core_bind.cpp15
-rw-r--r--core/core_bind.h2
-rw-r--r--core/error/error_macros.cpp22
-rw-r--r--core/error/error_macros.h1
-rw-r--r--core/extension/extension_api_dump.cpp1
-rw-r--r--core/input/input.cpp2
-rw-r--r--core/math/geometry_2d.h12
-rw-r--r--core/string/char_range.inc613
-rw-r--r--core/string/char_utils.h66
-rw-r--r--core/string/ustring.cpp4
-rw-r--r--core/templates/a_hash_map.cpp41
-rw-r--r--core/templates/a_hash_map.h734
-rw-r--r--core/templates/hashfuncs.h7
-rw-r--r--core/variant/variant_op.cpp2
17 files changed, 1294 insertions, 246 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp
index 6bc2c39760..124b5990a5 100644
--- a/core/config/engine.cpp
+++ b/core/config/engine.cpp
@@ -321,6 +321,12 @@ bool Engine::is_extra_gpu_memory_tracking_enabled() const {
return extra_gpu_memory_tracking;
}
+#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
+bool Engine::is_accurate_breadcrumbs_enabled() const {
+ return accurate_breadcrumbs;
+}
+#endif
+
void Engine::set_print_to_stdout(bool p_enabled) {
CoreGlobals::print_line_enabled = p_enabled;
}
diff --git a/core/config/engine.h b/core/config/engine.h
index 61f6c05d74..ec089923b3 100644
--- a/core/config/engine.h
+++ b/core/config/engine.h
@@ -75,6 +75,9 @@ private:
bool use_validation_layers = false;
bool generate_spirv_debug_info = false;
bool extra_gpu_memory_tracking = false;
+#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
+ bool accurate_breadcrumbs = false;
+#endif
int32_t gpu_idx = -1;
uint64_t _process_frames = 0;
@@ -191,6 +194,9 @@ public:
bool is_validation_layers_enabled() const;
bool is_generate_spirv_debug_info_enabled() const;
bool is_extra_gpu_memory_tracking_enabled() const;
+#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
+ bool is_accurate_breadcrumbs_enabled() const;
+#endif
int32_t get_gpu_index() const;
void increment_frames_drawn();
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 0d11e335aa..6ac61ecbee 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -517,9 +517,9 @@ void ProjectSettings::_convert_to_last_version(int p_from_version) {
Dictionary action = E.value.variant;
Array events = action["events"];
for (int i = 0; i < events.size(); i++) {
- Ref<InputEvent> x = events[i];
- if (x->get_device() == -1) { // -1 was the previous value (GH-97707).
- x->set_device(InputEvent::DEVICE_ID_ALL_DEVICES);
+ Ref<InputEvent> ev = events[i];
+ if (ev.is_valid() && ev->get_device() == -1) { // -1 was the previous value (GH-97707).
+ ev->set_device(InputEvent::DEVICE_ID_ALL_DEVICES);
}
}
}
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 401309487a..818185f131 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -922,6 +922,19 @@ Dictionary Geometry2D::make_atlas(const Vector<Size2> &p_rects) {
return ret;
}
+TypedArray<Point2i> Geometry2D::bresenham_line(const Point2i &p_from, const Point2i &p_to) {
+ Vector<Point2i> points = ::Geometry2D::bresenham_line(p_from, p_to);
+
+ TypedArray<Point2i> result;
+ result.resize(points.size());
+
+ for (int i = 0; i < points.size(); i++) {
+ result[i] = points[i];
+ }
+
+ return result;
+}
+
void Geometry2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_point_in_circle", "point", "circle_position", "circle_radius"), &Geometry2D::is_point_in_circle);
ClassDB::bind_method(D_METHOD("segment_intersects_circle", "segment_from", "segment_to", "circle_position", "circle_radius"), &Geometry2D::segment_intersects_circle);
@@ -956,6 +969,8 @@ void Geometry2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &Geometry2D::make_atlas);
+ ClassDB::bind_method(D_METHOD("bresenham_line", "from", "to"), &Geometry2D::bresenham_line);
+
BIND_ENUM_CONSTANT(OPERATION_UNION);
BIND_ENUM_CONSTANT(OPERATION_DIFFERENCE);
BIND_ENUM_CONSTANT(OPERATION_INTERSECTION);
diff --git a/core/core_bind.h b/core/core_bind.h
index e3a4bce890..e44268d539 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -326,6 +326,8 @@ public:
Dictionary make_atlas(const Vector<Size2> &p_rects);
+ TypedArray<Point2i> bresenham_line(const Point2i &p_from, const Point2i &p_to);
+
Geometry2D() { singleton = this; }
};
diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp
index d0503151ea..d226bf527a 100644
--- a/core/error/error_macros.cpp
+++ b/core/error/error_macros.cpp
@@ -109,6 +109,28 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
_global_unlock();
}
+// For printing errors when we may crash at any point, so we must flush ASAP a lot of lines
+// but we don't want to make it noisy by printing lots of file & line info (because it's already
+// been printing by a preceding _err_print_error).
+void _err_print_error_asap(const String &p_error, ErrorHandlerType p_type) {
+ if (OS::get_singleton()) {
+ OS::get_singleton()->printerr("ERROR: %s\n", p_error.utf8().get_data());
+ } else {
+ // Fallback if errors happen before OS init or after it's destroyed.
+ const char *err_details = p_error.utf8().get_data();
+ fprintf(stderr, "ERROR: %s\n", err_details);
+ }
+
+ _global_lock();
+ ErrorHandlerList *l = error_handler_list;
+ while (l) {
+ l->errfunc(l->userdata, "", "", 0, p_error.utf8().get_data(), "", false, p_type);
+ l = l->next;
+ }
+
+ _global_unlock();
+}
+
// Errors with message. (All combinations of p_error and p_message as String or char*.)
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) {
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_editor_notify, p_type);
diff --git a/core/error/error_macros.h b/core/error/error_macros.h
index 571a1568bd..f9fde7a146 100644
--- a/core/error/error_macros.h
+++ b/core/error/error_macros.h
@@ -70,6 +70,7 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error_asap(const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false);
void _err_flush_stdout();
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 05c3b5e8d6..2033ff2b43 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -117,6 +117,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
header["version_patch"] = 0;
#endif
header["version_status"] = VERSION_STATUS;
+ header["version_status_version"] = VERSION_STATUS_VERSION;
header["version_build"] = VERSION_BUILD;
header["version_full_name"] = VERSION_FULL_NAME;
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 11a1315c2f..695d3f131a 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -692,6 +692,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
button_event->set_canceled(st->is_canceled());
button_event->set_button_index(MouseButton::LEFT);
button_event->set_double_click(st->is_double_tap());
+ button_event->set_window_id(st->get_window_id());
BitField<MouseButtonMask> ev_bm = mouse_button_mask;
if (st->is_pressed()) {
@@ -729,6 +730,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
motion_event->set_velocity(sd->get_velocity());
motion_event->set_screen_velocity(sd->get_screen_velocity());
motion_event->set_button_mask(mouse_button_mask);
+ motion_event->set_window_id(sd->get_window_id());
_parse_input_event_impl(motion_event, true);
}
diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h
index c32d9187af..929d69ffc9 100644
--- a/core/math/geometry_2d.h
+++ b/core/math/geometry_2d.h
@@ -453,17 +453,17 @@ public:
return H;
}
- static Vector<Point2i> bresenham_line(const Point2i &p_start, const Point2i &p_end) {
+ static Vector<Point2i> bresenham_line(const Point2i &p_from, const Point2i &p_to) {
Vector<Point2i> points;
- Vector2i delta = (p_end - p_start).abs() * 2;
- Vector2i step = (p_end - p_start).sign();
- Vector2i current = p_start;
+ Vector2i delta = (p_to - p_from).abs() * 2;
+ Vector2i step = (p_to - p_from).sign();
+ Vector2i current = p_from;
if (delta.x > delta.y) {
int err = delta.x / 2;
- for (; current.x != p_end.x; current.x += step.x) {
+ for (; current.x != p_to.x; current.x += step.x) {
points.push_back(current);
err -= delta.y;
@@ -475,7 +475,7 @@ public:
} else {
int err = delta.y / 2;
- for (; current.y != p_end.y; current.y += step.y) {
+ for (; current.y != p_to.y; current.y += step.y) {
points.push_back(current);
err -= delta.x;
diff --git a/core/string/char_range.inc b/core/string/char_range.inc
index d5937d9616..6beab0d072 100644
--- a/core/string/char_range.inc
+++ b/core/string/char_range.inc
@@ -35,14 +35,17 @@
#include "core/typedefs.h"
+// Unicode Derived Core Properties
+// Source: https://www.unicode.org/Public/16.0.0/ucd/DerivedCoreProperties.txt
+
struct CharRange {
char32_t start;
char32_t end;
};
-inline constexpr CharRange xid_start[] = {
+constexpr inline CharRange xid_start[] = {
{ 0x41, 0x5a },
- { 0x5f, 0x5f },
+ { 0x5f, 0x5f }, // Underscore technically isn't in XID_Start, but for our purposes it's included.
{ 0x61, 0x7a },
{ 0xaa, 0xaa },
{ 0xb5, 0xb5 },
@@ -56,7 +59,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x2ee, 0x2ee },
{ 0x370, 0x374 },
{ 0x376, 0x377 },
- { 0x37a, 0x37d },
+ { 0x37b, 0x37d },
{ 0x37f, 0x37f },
{ 0x386, 0x386 },
{ 0x388, 0x38a },
@@ -184,7 +187,7 @@ inline constexpr CharRange xid_start[] = {
{ 0xdbd, 0xdbd },
{ 0xdc0, 0xdc6 },
{ 0xe01, 0xe30 },
- { 0xe32, 0xe33 },
+ { 0xe32, 0xe32 },
{ 0xe40, 0xe46 },
{ 0xe81, 0xe82 },
{ 0xe84, 0xe84 },
@@ -192,7 +195,7 @@ inline constexpr CharRange xid_start[] = {
{ 0xe8c, 0xea3 },
{ 0xea5, 0xea5 },
{ 0xea7, 0xeb0 },
- { 0xeb2, 0xeb3 },
+ { 0xeb2, 0xeb2 },
{ 0xebd, 0xebd },
{ 0xec0, 0xec4 },
{ 0xec6, 0xec6 },
@@ -247,8 +250,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x17d7, 0x17d7 },
{ 0x17dc, 0x17dc },
{ 0x1820, 0x1878 },
- { 0x1880, 0x1884 },
- { 0x1887, 0x18a8 },
+ { 0x1880, 0x18a8 },
{ 0x18aa, 0x18aa },
{ 0x18b0, 0x18f5 },
{ 0x1900, 0x191e },
@@ -267,7 +269,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x1c00, 0x1c23 },
{ 0x1c4d, 0x1c4f },
{ 0x1c5a, 0x1c7d },
- { 0x1c80, 0x1c88 },
+ { 0x1c80, 0x1c8a },
{ 0x1c90, 0x1cba },
{ 0x1cbd, 0x1cbf },
{ 0x1ce9, 0x1cec },
@@ -332,7 +334,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x3031, 0x3035 },
{ 0x3038, 0x303c },
{ 0x3041, 0x3096 },
- { 0x309b, 0x309f },
+ { 0x309d, 0x309f },
{ 0x30a1, 0x30fa },
{ 0x30fc, 0x30ff },
{ 0x3105, 0x312f },
@@ -350,10 +352,10 @@ inline constexpr CharRange xid_start[] = {
{ 0xa6a0, 0xa6ef },
{ 0xa717, 0xa71f },
{ 0xa722, 0xa788 },
- { 0xa78b, 0xa7ca },
+ { 0xa78b, 0xa7cd },
{ 0xa7d0, 0xa7d1 },
{ 0xa7d3, 0xa7d3 },
- { 0xa7d5, 0xa7d9 },
+ { 0xa7d5, 0xa7dc },
{ 0xa7f2, 0xa801 },
{ 0xa803, 0xa805 },
{ 0xa807, 0xa80a },
@@ -408,15 +410,22 @@ inline constexpr CharRange xid_start[] = {
{ 0xfb40, 0xfb41 },
{ 0xfb43, 0xfb44 },
{ 0xfb46, 0xfbb1 },
- { 0xfbd3, 0xfd3d },
+ { 0xfbd3, 0xfc5d },
+ { 0xfc64, 0xfd3d },
{ 0xfd50, 0xfd8f },
{ 0xfd92, 0xfdc7 },
- { 0xfdf0, 0xfdfb },
- { 0xfe70, 0xfe74 },
- { 0xfe76, 0xfefc },
+ { 0xfdf0, 0xfdf9 },
+ { 0xfe71, 0xfe71 },
+ { 0xfe73, 0xfe73 },
+ { 0xfe77, 0xfe77 },
+ { 0xfe79, 0xfe79 },
+ { 0xfe7b, 0xfe7b },
+ { 0xfe7d, 0xfe7d },
+ { 0xfe7f, 0xfefc },
{ 0xff21, 0xff3a },
{ 0xff41, 0xff5a },
- { 0xff66, 0xffbe },
+ { 0xff66, 0xff9d },
+ { 0xffa0, 0xffbe },
{ 0xffc2, 0xffc7 },
{ 0xffca, 0xffcf },
{ 0xffd2, 0xffd7 },
@@ -451,6 +460,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x105a3, 0x105b1 },
{ 0x105b3, 0x105b9 },
{ 0x105bb, 0x105bc },
+ { 0x105c0, 0x105f3 },
{ 0x10600, 0x10736 },
{ 0x10740, 0x10755 },
{ 0x10760, 0x10767 },
@@ -487,8 +497,11 @@ inline constexpr CharRange xid_start[] = {
{ 0x10c80, 0x10cb2 },
{ 0x10cc0, 0x10cf2 },
{ 0x10d00, 0x10d23 },
+ { 0x10d4a, 0x10d65 },
+ { 0x10d6f, 0x10d85 },
{ 0x10e80, 0x10ea9 },
{ 0x10eb0, 0x10eb1 },
+ { 0x10ec2, 0x10ec4 },
{ 0x10f00, 0x10f1c },
{ 0x10f27, 0x10f27 },
{ 0x10f30, 0x10f45 },
@@ -511,6 +524,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x111dc, 0x111dc },
{ 0x11200, 0x11211 },
{ 0x11213, 0x1122b },
+ { 0x1123f, 0x11240 },
{ 0x11280, 0x11286 },
{ 0x11288, 0x11288 },
{ 0x1128a, 0x1128d },
@@ -526,6 +540,13 @@ inline constexpr CharRange xid_start[] = {
{ 0x1133d, 0x1133d },
{ 0x11350, 0x11350 },
{ 0x1135d, 0x11361 },
+ { 0x11380, 0x11389 },
+ { 0x1138b, 0x1138b },
+ { 0x1138e, 0x1138e },
+ { 0x11390, 0x113b5 },
+ { 0x113b7, 0x113b7 },
+ { 0x113d1, 0x113d1 },
+ { 0x113d3, 0x113d3 },
{ 0x11400, 0x11434 },
{ 0x11447, 0x1144a },
{ 0x1145f, 0x11461 },
@@ -560,6 +581,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x11a5c, 0x11a89 },
{ 0x11a9d, 0x11a9d },
{ 0x11ab0, 0x11af8 },
+ { 0x11bc0, 0x11be0 },
{ 0x11c00, 0x11c08 },
{ 0x11c0a, 0x11c2e },
{ 0x11c40, 0x11c40 },
@@ -573,13 +595,19 @@ inline constexpr CharRange xid_start[] = {
{ 0x11d6a, 0x11d89 },
{ 0x11d98, 0x11d98 },
{ 0x11ee0, 0x11ef2 },
+ { 0x11f02, 0x11f02 },
+ { 0x11f04, 0x11f10 },
+ { 0x11f12, 0x11f33 },
{ 0x11fb0, 0x11fb0 },
{ 0x12000, 0x12399 },
{ 0x12400, 0x1246e },
{ 0x12480, 0x12543 },
{ 0x12f90, 0x12ff0 },
- { 0x13000, 0x1342e },
+ { 0x13000, 0x1342f },
+ { 0x13441, 0x13446 },
+ { 0x13460, 0x143fa },
{ 0x14400, 0x14646 },
+ { 0x16100, 0x1611d },
{ 0x16800, 0x16a38 },
{ 0x16a40, 0x16a5e },
{ 0x16a70, 0x16abe },
@@ -588,6 +616,7 @@ inline constexpr CharRange xid_start[] = {
{ 0x16b40, 0x16b43 },
{ 0x16b63, 0x16b77 },
{ 0x16b7d, 0x16b8f },
+ { 0x16d40, 0x16d6c },
{ 0x16e40, 0x16e7f },
{ 0x16f00, 0x16f4a },
{ 0x16f50, 0x16f50 },
@@ -596,12 +625,14 @@ inline constexpr CharRange xid_start[] = {
{ 0x16fe3, 0x16fe3 },
{ 0x17000, 0x187f7 },
{ 0x18800, 0x18cd5 },
- { 0x18d00, 0x18d08 },
+ { 0x18cff, 0x18d08 },
{ 0x1aff0, 0x1aff3 },
{ 0x1aff5, 0x1affb },
{ 0x1affd, 0x1affe },
{ 0x1b000, 0x1b122 },
+ { 0x1b132, 0x1b132 },
{ 0x1b150, 0x1b152 },
+ { 0x1b155, 0x1b155 },
{ 0x1b164, 0x1b167 },
{ 0x1b170, 0x1b2fb },
{ 0x1bc00, 0x1bc6a },
@@ -639,11 +670,16 @@ inline constexpr CharRange xid_start[] = {
{ 0x1d7aa, 0x1d7c2 },
{ 0x1d7c4, 0x1d7cb },
{ 0x1df00, 0x1df1e },
+ { 0x1df25, 0x1df2a },
+ { 0x1e030, 0x1e06d },
{ 0x1e100, 0x1e12c },
{ 0x1e137, 0x1e13d },
{ 0x1e14e, 0x1e14e },
{ 0x1e290, 0x1e2ad },
{ 0x1e2c0, 0x1e2eb },
+ { 0x1e4d0, 0x1e4eb },
+ { 0x1e5d0, 0x1e5ed },
+ { 0x1e5f0, 0x1e5f0 },
{ 0x1e7e0, 0x1e7e6 },
{ 0x1e7e8, 0x1e7eb },
{ 0x1e7ed, 0x1e7ee },
@@ -685,15 +721,17 @@ inline constexpr CharRange xid_start[] = {
{ 0x1eea5, 0x1eea9 },
{ 0x1eeab, 0x1eebb },
{ 0x20000, 0x2a6df },
- { 0x2a700, 0x2b738 },
+ { 0x2a700, 0x2b739 },
{ 0x2b740, 0x2b81d },
{ 0x2b820, 0x2cea1 },
{ 0x2ceb0, 0x2ebe0 },
+ { 0x2ebf0, 0x2ee5d },
{ 0x2f800, 0x2fa1d },
{ 0x30000, 0x3134a },
+ { 0x31350, 0x323af },
};
-inline constexpr CharRange xid_continue[] = {
+constexpr inline CharRange xid_continue[] = {
{ 0x30, 0x39 },
{ 0x41, 0x5a },
{ 0x5f, 0x5f },
@@ -711,7 +749,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x2ee, 0x2ee },
{ 0x300, 0x374 },
{ 0x376, 0x377 },
- { 0x37a, 0x37d },
+ { 0x37b, 0x37d },
{ 0x37f, 0x37f },
{ 0x386, 0x38a },
{ 0x38c, 0x38c },
@@ -747,7 +785,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x860, 0x86a },
{ 0x870, 0x887 },
{ 0x889, 0x88e },
- { 0x898, 0x8e1 },
+ { 0x897, 0x8e1 },
{ 0x8e3, 0x963 },
{ 0x966, 0x96f },
{ 0x971, 0x983 },
@@ -852,7 +890,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0xcdd, 0xcde },
{ 0xce0, 0xce3 },
{ 0xce6, 0xcef },
- { 0xcf1, 0xcf2 },
+ { 0xcf1, 0xcf3 },
{ 0xd00, 0xd0c },
{ 0xd0e, 0xd10 },
{ 0xd12, 0xd44 },
@@ -885,7 +923,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0xea7, 0xebd },
{ 0xec0, 0xec4 },
{ 0xec6, 0xec6 },
- { 0xec8, 0xecd },
+ { 0xec8, 0xece },
{ 0xed0, 0xed9 },
{ 0xedc, 0xedf },
{ 0xf00, 0xf00 },
@@ -923,8 +961,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1312, 0x1315 },
{ 0x1318, 0x135a },
{ 0x135d, 0x135f },
- { 0x1369, 0x1369 },
- { 0x1371, 0x1371 },
+ { 0x1369, 0x1371 },
{ 0x1380, 0x138f },
{ 0x13a0, 0x13f5 },
{ 0x13f8, 0x13fd },
@@ -971,7 +1008,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1c00, 0x1c37 },
{ 0x1c40, 0x1c49 },
{ 0x1c4d, 0x1c7d },
- { 0x1c80, 0x1c88 },
+ { 0x1c80, 0x1c8a },
{ 0x1c90, 0x1cba },
{ 0x1cbd, 0x1cbf },
{ 0x1cd0, 0x1cd2 },
@@ -995,6 +1032,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1fe0, 0x1fec },
{ 0x1ff2, 0x1ff4 },
{ 0x1ff6, 0x1ffc },
+ { 0x200c, 0x200d },
{ 0x203f, 0x2040 },
{ 0x2054, 0x2054 },
{ 0x2071, 0x2071 },
@@ -1038,9 +1076,9 @@ inline constexpr CharRange xid_continue[] = {
{ 0x3031, 0x3035 },
{ 0x3038, 0x303c },
{ 0x3041, 0x3096 },
- { 0x3099, 0x309f },
- { 0x30a1, 0x30fa },
- { 0x30fc, 0x30ff },
+ { 0x3099, 0x309a },
+ { 0x309d, 0x309f },
+ { 0x30a1, 0x30ff },
{ 0x3105, 0x312f },
{ 0x3131, 0x318e },
{ 0x31a0, 0x31bf },
@@ -1055,10 +1093,10 @@ inline constexpr CharRange xid_continue[] = {
{ 0xa67f, 0xa6f1 },
{ 0xa717, 0xa71f },
{ 0xa722, 0xa788 },
- { 0xa78b, 0xa7ca },
+ { 0xa78b, 0xa7cd },
{ 0xa7d0, 0xa7d1 },
{ 0xa7d3, 0xa7d3 },
- { 0xa7d5, 0xa7d9 },
+ { 0xa7d5, 0xa7dc },
{ 0xa7f2, 0xa827 },
{ 0xa82c, 0xa82c },
{ 0xa840, 0xa873 },
@@ -1104,21 +1142,27 @@ inline constexpr CharRange xid_continue[] = {
{ 0xfb40, 0xfb41 },
{ 0xfb43, 0xfb44 },
{ 0xfb46, 0xfbb1 },
- { 0xfbd3, 0xfd3d },
+ { 0xfbd3, 0xfc5d },
+ { 0xfc64, 0xfd3d },
{ 0xfd50, 0xfd8f },
{ 0xfd92, 0xfdc7 },
- { 0xfdf0, 0xfdfb },
+ { 0xfdf0, 0xfdf9 },
{ 0xfe00, 0xfe0f },
{ 0xfe20, 0xfe2f },
{ 0xfe33, 0xfe34 },
{ 0xfe4d, 0xfe4f },
- { 0xfe70, 0xfe74 },
- { 0xfe76, 0xfefc },
+ { 0xfe71, 0xfe71 },
+ { 0xfe73, 0xfe73 },
+ { 0xfe77, 0xfe77 },
+ { 0xfe79, 0xfe79 },
+ { 0xfe7b, 0xfe7b },
+ { 0xfe7d, 0xfe7d },
+ { 0xfe7f, 0xfefc },
{ 0xff10, 0xff19 },
{ 0xff21, 0xff3a },
{ 0xff3f, 0xff3f },
{ 0xff41, 0xff5a },
- { 0xff66, 0xffbe },
+ { 0xff65, 0xffbe },
{ 0xffc2, 0xffc7 },
{ 0xffca, 0xffcf },
{ 0xffd2, 0xffd7 },
@@ -1156,6 +1200,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x105a3, 0x105b1 },
{ 0x105b3, 0x105b9 },
{ 0x105bb, 0x105bc },
+ { 0x105c0, 0x105f3 },
{ 0x10600, 0x10736 },
{ 0x10740, 0x10755 },
{ 0x10760, 0x10767 },
@@ -1196,10 +1241,14 @@ inline constexpr CharRange xid_continue[] = {
{ 0x10cc0, 0x10cf2 },
{ 0x10d00, 0x10d27 },
{ 0x10d30, 0x10d39 },
+ { 0x10d40, 0x10d65 },
+ { 0x10d69, 0x10d6d },
+ { 0x10d6f, 0x10d85 },
{ 0x10e80, 0x10ea9 },
{ 0x10eab, 0x10eac },
{ 0x10eb0, 0x10eb1 },
- { 0x10f00, 0x10f1c },
+ { 0x10ec2, 0x10ec4 },
+ { 0x10efc, 0x10f1c },
{ 0x10f27, 0x10f27 },
{ 0x10f30, 0x10f50 },
{ 0x10f70, 0x10f85 },
@@ -1222,7 +1271,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x111dc, 0x111dc },
{ 0x11200, 0x11211 },
{ 0x11213, 0x11237 },
- { 0x1123e, 0x1123e },
+ { 0x1123e, 0x11241 },
{ 0x11280, 0x11286 },
{ 0x11288, 0x11288 },
{ 0x1128a, 0x1128d },
@@ -1245,6 +1294,16 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1135d, 0x11363 },
{ 0x11366, 0x1136c },
{ 0x11370, 0x11374 },
+ { 0x11380, 0x11389 },
+ { 0x1138b, 0x1138b },
+ { 0x1138e, 0x1138e },
+ { 0x11390, 0x113b5 },
+ { 0x113b7, 0x113c0 },
+ { 0x113c2, 0x113c2 },
+ { 0x113c5, 0x113c5 },
+ { 0x113c7, 0x113ca },
+ { 0x113cc, 0x113d3 },
+ { 0x113e1, 0x113e2 },
{ 0x11400, 0x1144a },
{ 0x11450, 0x11459 },
{ 0x1145e, 0x11461 },
@@ -1259,6 +1318,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x11650, 0x11659 },
{ 0x11680, 0x116b8 },
{ 0x116c0, 0x116c9 },
+ { 0x116d0, 0x116e3 },
{ 0x11700, 0x1171a },
{ 0x1171d, 0x1172b },
{ 0x11730, 0x11739 },
@@ -1282,6 +1342,8 @@ inline constexpr CharRange xid_continue[] = {
{ 0x11a50, 0x11a99 },
{ 0x11a9d, 0x11a9d },
{ 0x11ab0, 0x11af8 },
+ { 0x11bc0, 0x11be0 },
+ { 0x11bf0, 0x11bf9 },
{ 0x11c00, 0x11c08 },
{ 0x11c0a, 0x11c36 },
{ 0x11c38, 0x11c40 },
@@ -1303,13 +1365,20 @@ inline constexpr CharRange xid_continue[] = {
{ 0x11d93, 0x11d98 },
{ 0x11da0, 0x11da9 },
{ 0x11ee0, 0x11ef6 },
+ { 0x11f00, 0x11f10 },
+ { 0x11f12, 0x11f3a },
+ { 0x11f3e, 0x11f42 },
+ { 0x11f50, 0x11f5a },
{ 0x11fb0, 0x11fb0 },
{ 0x12000, 0x12399 },
{ 0x12400, 0x1246e },
{ 0x12480, 0x12543 },
{ 0x12f90, 0x12ff0 },
- { 0x13000, 0x1342e },
+ { 0x13000, 0x1342f },
+ { 0x13440, 0x13455 },
+ { 0x13460, 0x143fa },
{ 0x14400, 0x14646 },
+ { 0x16100, 0x16139 },
{ 0x16800, 0x16a38 },
{ 0x16a40, 0x16a5e },
{ 0x16a60, 0x16a69 },
@@ -1322,6 +1391,8 @@ inline constexpr CharRange xid_continue[] = {
{ 0x16b50, 0x16b59 },
{ 0x16b63, 0x16b77 },
{ 0x16b7d, 0x16b8f },
+ { 0x16d40, 0x16d6c },
+ { 0x16d70, 0x16d79 },
{ 0x16e40, 0x16e7f },
{ 0x16f00, 0x16f4a },
{ 0x16f4f, 0x16f87 },
@@ -1331,12 +1402,14 @@ inline constexpr CharRange xid_continue[] = {
{ 0x16ff0, 0x16ff1 },
{ 0x17000, 0x187f7 },
{ 0x18800, 0x18cd5 },
- { 0x18d00, 0x18d08 },
+ { 0x18cff, 0x18d08 },
{ 0x1aff0, 0x1aff3 },
{ 0x1aff5, 0x1affb },
{ 0x1affd, 0x1affe },
{ 0x1b000, 0x1b122 },
+ { 0x1b132, 0x1b132 },
{ 0x1b150, 0x1b152 },
+ { 0x1b155, 0x1b155 },
{ 0x1b164, 0x1b167 },
{ 0x1b170, 0x1b2fb },
{ 0x1bc00, 0x1bc6a },
@@ -1344,6 +1417,7 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1bc80, 0x1bc88 },
{ 0x1bc90, 0x1bc99 },
{ 0x1bc9d, 0x1bc9e },
+ { 0x1ccf0, 0x1ccf9 },
{ 0x1cf00, 0x1cf2d },
{ 0x1cf30, 0x1cf46 },
{ 0x1d165, 0x1d169 },
@@ -1390,17 +1464,22 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1da9b, 0x1da9f },
{ 0x1daa1, 0x1daaf },
{ 0x1df00, 0x1df1e },
+ { 0x1df25, 0x1df2a },
{ 0x1e000, 0x1e006 },
{ 0x1e008, 0x1e018 },
{ 0x1e01b, 0x1e021 },
{ 0x1e023, 0x1e024 },
{ 0x1e026, 0x1e02a },
+ { 0x1e030, 0x1e06d },
+ { 0x1e08f, 0x1e08f },
{ 0x1e100, 0x1e12c },
{ 0x1e130, 0x1e13d },
{ 0x1e140, 0x1e149 },
{ 0x1e14e, 0x1e14e },
{ 0x1e290, 0x1e2ae },
{ 0x1e2c0, 0x1e2f9 },
+ { 0x1e4d0, 0x1e4f9 },
+ { 0x1e5d0, 0x1e5fa },
{ 0x1e7e0, 0x1e7e6 },
{ 0x1e7e8, 0x1e7eb },
{ 0x1e7ed, 0x1e7ee },
@@ -1444,16 +1523,18 @@ inline constexpr CharRange xid_continue[] = {
{ 0x1eeab, 0x1eebb },
{ 0x1fbf0, 0x1fbf9 },
{ 0x20000, 0x2a6df },
- { 0x2a700, 0x2b738 },
+ { 0x2a700, 0x2b739 },
{ 0x2b740, 0x2b81d },
{ 0x2b820, 0x2cea1 },
{ 0x2ceb0, 0x2ebe0 },
+ { 0x2ebf0, 0x2ee5d },
{ 0x2f800, 0x2fa1d },
{ 0x30000, 0x3134a },
+ { 0x31350, 0x323af },
{ 0xe0100, 0xe01ef },
};
-inline constexpr CharRange uppercase_letter[] = {
+constexpr inline CharRange uppercase_letter[] = {
{ 0x41, 0x5a },
{ 0xc0, 0xd6 },
{ 0xd8, 0xde },
@@ -1730,6 +1811,7 @@ inline constexpr CharRange uppercase_letter[] = {
{ 0x10c7, 0x10c7 },
{ 0x10cd, 0x10cd },
{ 0x13a0, 0x13f5 },
+ { 0x1c89, 0x1c89 },
{ 0x1c90, 0x1cba },
{ 0x1cbd, 0x1cbf },
{ 0x1e00, 0x1e00 },
@@ -1884,7 +1966,9 @@ inline constexpr CharRange uppercase_letter[] = {
{ 0x2130, 0x2133 },
{ 0x213e, 0x213f },
{ 0x2145, 0x2145 },
+ { 0x2160, 0x216f },
{ 0x2183, 0x2183 },
+ { 0x24b6, 0x24cf },
{ 0x2c00, 0x2c2f },
{ 0x2c60, 0x2c60 },
{ 0x2c62, 0x2c64 },
@@ -2054,9 +2138,12 @@ inline constexpr CharRange uppercase_letter[] = {
{ 0xa7c2, 0xa7c2 },
{ 0xa7c4, 0xa7c7 },
{ 0xa7c9, 0xa7c9 },
+ { 0xa7cb, 0xa7cc },
{ 0xa7d0, 0xa7d0 },
{ 0xa7d6, 0xa7d6 },
{ 0xa7d8, 0xa7d8 },
+ { 0xa7da, 0xa7da },
+ { 0xa7dc, 0xa7dc },
{ 0xa7f5, 0xa7f5 },
{ 0xff21, 0xff3a },
{ 0x10400, 0x10427 },
@@ -2066,6 +2153,7 @@ inline constexpr CharRange uppercase_letter[] = {
{ 0x1058c, 0x10592 },
{ 0x10594, 0x10595 },
{ 0x10c80, 0x10cb2 },
+ { 0x10d50, 0x10d65 },
{ 0x118a0, 0x118bf },
{ 0x16e40, 0x16e5f },
{ 0x1d400, 0x1d419 },
@@ -2100,11 +2188,16 @@ inline constexpr CharRange uppercase_letter[] = {
{ 0x1d790, 0x1d7a8 },
{ 0x1d7ca, 0x1d7ca },
{ 0x1e900, 0x1e921 },
+ { 0x1f130, 0x1f149 },
+ { 0x1f150, 0x1f169 },
+ { 0x1f170, 0x1f189 },
};
-inline constexpr CharRange lowercase_letter[] = {
+constexpr inline CharRange lowercase_letter[] = {
{ 0x61, 0x7a },
+ { 0xaa, 0xaa },
{ 0xb5, 0xb5 },
+ { 0xba, 0xba },
{ 0xdf, 0xf6 },
{ 0xf8, 0xff },
{ 0x101, 0x101 },
@@ -2248,11 +2341,14 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x24b, 0x24b },
{ 0x24d, 0x24d },
{ 0x24f, 0x293 },
- { 0x295, 0x2af },
+ { 0x295, 0x2b8 },
+ { 0x2c0, 0x2c1 },
+ { 0x2e0, 0x2e4 },
+ { 0x345, 0x345 },
{ 0x371, 0x371 },
{ 0x373, 0x373 },
{ 0x377, 0x377 },
- { 0x37b, 0x37d },
+ { 0x37a, 0x37d },
{ 0x390, 0x390 },
{ 0x3ac, 0x3ce },
{ 0x3d0, 0x3d1 },
@@ -2374,12 +2470,11 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x52f, 0x52f },
{ 0x560, 0x588 },
{ 0x10d0, 0x10fa },
- { 0x10fd, 0x10ff },
+ { 0x10fc, 0x10ff },
{ 0x13f8, 0x13fd },
{ 0x1c80, 0x1c88 },
- { 0x1d00, 0x1d2b },
- { 0x1d6b, 0x1d77 },
- { 0x1d79, 0x1d9a },
+ { 0x1c8a, 0x1c8a },
+ { 0x1d00, 0x1dbf },
{ 0x1e01, 0x1e01 },
{ 0x1e03, 0x1e03 },
{ 0x1e05, 0x1e05 },
@@ -2524,6 +2619,9 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x1fe0, 0x1fe7 },
{ 0x1ff2, 0x1ff4 },
{ 0x1ff6, 0x1ff7 },
+ { 0x2071, 0x2071 },
+ { 0x207f, 0x207f },
+ { 0x2090, 0x209c },
{ 0x210a, 0x210a },
{ 0x210e, 0x210f },
{ 0x2113, 0x2113 },
@@ -2533,7 +2631,9 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x213c, 0x213d },
{ 0x2146, 0x2149 },
{ 0x214e, 0x214e },
+ { 0x2170, 0x217f },
{ 0x2184, 0x2184 },
+ { 0x24d0, 0x24e9 },
{ 0x2c30, 0x2c5f },
{ 0x2c61, 0x2c61 },
{ 0x2c65, 0x2c66 },
@@ -2542,7 +2642,7 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x2c6c, 0x2c6c },
{ 0x2c71, 0x2c71 },
{ 0x2c73, 0x2c74 },
- { 0x2c76, 0x2c7b },
+ { 0x2c76, 0x2c7d },
{ 0x2c81, 0x2c81 },
{ 0x2c83, 0x2c83 },
{ 0x2c85, 0x2c85 },
@@ -2635,7 +2735,7 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0xa695, 0xa695 },
{ 0xa697, 0xa697 },
{ 0xa699, 0xa699 },
- { 0xa69b, 0xa69b },
+ { 0xa69b, 0xa69d },
{ 0xa723, 0xa723 },
{ 0xa725, 0xa725 },
{ 0xa727, 0xa727 },
@@ -2673,8 +2773,7 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0xa769, 0xa769 },
{ 0xa76b, 0xa76b },
{ 0xa76d, 0xa76d },
- { 0xa76f, 0xa76f },
- { 0xa771, 0xa778 },
+ { 0xa76f, 0xa778 },
{ 0xa77a, 0xa77a },
{ 0xa77c, 0xa77c },
{ 0xa77f, 0xa77f },
@@ -2707,15 +2806,18 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0xa7c3, 0xa7c3 },
{ 0xa7c8, 0xa7c8 },
{ 0xa7ca, 0xa7ca },
+ { 0xa7cd, 0xa7cd },
{ 0xa7d1, 0xa7d1 },
{ 0xa7d3, 0xa7d3 },
{ 0xa7d5, 0xa7d5 },
{ 0xa7d7, 0xa7d7 },
{ 0xa7d9, 0xa7d9 },
+ { 0xa7db, 0xa7db },
+ { 0xa7f2, 0xa7f4 },
{ 0xa7f6, 0xa7f6 },
- { 0xa7fa, 0xa7fa },
+ { 0xa7f8, 0xa7fa },
{ 0xab30, 0xab5a },
- { 0xab60, 0xab68 },
+ { 0xab5c, 0xab69 },
{ 0xab70, 0xabbf },
{ 0xfb00, 0xfb06 },
{ 0xfb13, 0xfb17 },
@@ -2726,7 +2828,12 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x105a3, 0x105b1 },
{ 0x105b3, 0x105b9 },
{ 0x105bb, 0x105bc },
+ { 0x10780, 0x10780 },
+ { 0x10783, 0x10785 },
+ { 0x10787, 0x107b0 },
+ { 0x107b2, 0x107ba },
{ 0x10cc0, 0x10cf2 },
+ { 0x10d70, 0x10d85 },
{ 0x118c0, 0x118df },
{ 0x16e60, 0x16e7f },
{ 0x1d41a, 0x1d433 },
@@ -2760,10 +2867,11 @@ inline constexpr CharRange lowercase_letter[] = {
{ 0x1df00, 0x1df09 },
{ 0x1df0b, 0x1df1e },
{ 0x1df25, 0x1df2a },
+ { 0x1e030, 0x1e06d },
{ 0x1e922, 0x1e943 },
};
-inline constexpr CharRange unicode_letter[] = {
+constexpr inline CharRange unicode_letter[] = {
{ 0x41, 0x5a },
{ 0x61, 0x7a },
{ 0xaa, 0xaa },
@@ -2776,7 +2884,8 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x2e0, 0x2e4 },
{ 0x2ec, 0x2ec },
{ 0x2ee, 0x2ee },
- { 0x370, 0x374 },
+ { 0x345, 0x345 },
+ { 0x363, 0x374 },
{ 0x376, 0x377 },
{ 0x37a, 0x37d },
{ 0x37f, 0x37f },
@@ -2790,49 +2899,58 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x531, 0x556 },
{ 0x559, 0x559 },
{ 0x560, 0x588 },
+ { 0x5b0, 0x5bd },
+ { 0x5bf, 0x5bf },
+ { 0x5c1, 0x5c2 },
+ { 0x5c4, 0x5c5 },
+ { 0x5c7, 0x5c7 },
{ 0x5d0, 0x5ea },
{ 0x5ef, 0x5f2 },
- { 0x620, 0x64a },
- { 0x66e, 0x66f },
- { 0x671, 0x6d3 },
- { 0x6d5, 0x6d5 },
- { 0x6e5, 0x6e6 },
- { 0x6ee, 0x6ef },
+ { 0x610, 0x61a },
+ { 0x620, 0x657 },
+ { 0x659, 0x65f },
+ { 0x66e, 0x6d3 },
+ { 0x6d5, 0x6dc },
+ { 0x6e1, 0x6e8 },
+ { 0x6ed, 0x6ef },
{ 0x6fa, 0x6fc },
{ 0x6ff, 0x6ff },
- { 0x710, 0x710 },
- { 0x712, 0x72f },
- { 0x74d, 0x7a5 },
- { 0x7b1, 0x7b1 },
+ { 0x710, 0x73f },
+ { 0x74d, 0x7b1 },
{ 0x7ca, 0x7ea },
{ 0x7f4, 0x7f5 },
{ 0x7fa, 0x7fa },
- { 0x800, 0x815 },
- { 0x81a, 0x81a },
- { 0x824, 0x824 },
- { 0x828, 0x828 },
+ { 0x800, 0x817 },
+ { 0x81a, 0x82c },
{ 0x840, 0x858 },
{ 0x860, 0x86a },
{ 0x870, 0x887 },
{ 0x889, 0x88e },
+ { 0x897, 0x897 },
{ 0x8a0, 0x8c9 },
- { 0x904, 0x939 },
- { 0x93d, 0x93d },
- { 0x950, 0x950 },
- { 0x958, 0x961 },
- { 0x971, 0x980 },
+ { 0x8d4, 0x8df },
+ { 0x8e3, 0x8e9 },
+ { 0x8f0, 0x93b },
+ { 0x93d, 0x94c },
+ { 0x94e, 0x950 },
+ { 0x955, 0x963 },
+ { 0x971, 0x983 },
{ 0x985, 0x98c },
{ 0x98f, 0x990 },
{ 0x993, 0x9a8 },
{ 0x9aa, 0x9b0 },
{ 0x9b2, 0x9b2 },
{ 0x9b6, 0x9b9 },
- { 0x9bd, 0x9bd },
+ { 0x9bd, 0x9c4 },
+ { 0x9c7, 0x9c8 },
+ { 0x9cb, 0x9cc },
{ 0x9ce, 0x9ce },
+ { 0x9d7, 0x9d7 },
{ 0x9dc, 0x9dd },
- { 0x9df, 0x9e1 },
+ { 0x9df, 0x9e3 },
{ 0x9f0, 0x9f1 },
{ 0x9fc, 0x9fc },
+ { 0xa01, 0xa03 },
{ 0xa05, 0xa0a },
{ 0xa0f, 0xa10 },
{ 0xa13, 0xa28 },
@@ -2840,30 +2958,41 @@ inline constexpr CharRange unicode_letter[] = {
{ 0xa32, 0xa33 },
{ 0xa35, 0xa36 },
{ 0xa38, 0xa39 },
+ { 0xa3e, 0xa42 },
+ { 0xa47, 0xa48 },
+ { 0xa4b, 0xa4c },
+ { 0xa51, 0xa51 },
{ 0xa59, 0xa5c },
{ 0xa5e, 0xa5e },
- { 0xa72, 0xa74 },
+ { 0xa70, 0xa75 },
+ { 0xa81, 0xa83 },
{ 0xa85, 0xa8d },
{ 0xa8f, 0xa91 },
{ 0xa93, 0xaa8 },
{ 0xaaa, 0xab0 },
{ 0xab2, 0xab3 },
{ 0xab5, 0xab9 },
- { 0xabd, 0xabd },
+ { 0xabd, 0xac5 },
+ { 0xac7, 0xac9 },
+ { 0xacb, 0xacc },
{ 0xad0, 0xad0 },
- { 0xae0, 0xae1 },
- { 0xaf9, 0xaf9 },
+ { 0xae0, 0xae3 },
+ { 0xaf9, 0xafc },
+ { 0xb01, 0xb03 },
{ 0xb05, 0xb0c },
{ 0xb0f, 0xb10 },
{ 0xb13, 0xb28 },
{ 0xb2a, 0xb30 },
{ 0xb32, 0xb33 },
{ 0xb35, 0xb39 },
- { 0xb3d, 0xb3d },
+ { 0xb3d, 0xb44 },
+ { 0xb47, 0xb48 },
+ { 0xb4b, 0xb4c },
+ { 0xb56, 0xb57 },
{ 0xb5c, 0xb5d },
- { 0xb5f, 0xb61 },
+ { 0xb5f, 0xb63 },
{ 0xb71, 0xb71 },
- { 0xb83, 0xb83 },
+ { 0xb82, 0xb83 },
{ 0xb85, 0xb8a },
{ 0xb8e, 0xb90 },
{ 0xb92, 0xb95 },
@@ -2873,65 +3002,80 @@ inline constexpr CharRange unicode_letter[] = {
{ 0xba3, 0xba4 },
{ 0xba8, 0xbaa },
{ 0xbae, 0xbb9 },
+ { 0xbbe, 0xbc2 },
+ { 0xbc6, 0xbc8 },
+ { 0xbca, 0xbcc },
{ 0xbd0, 0xbd0 },
- { 0xc05, 0xc0c },
+ { 0xbd7, 0xbd7 },
+ { 0xc00, 0xc0c },
{ 0xc0e, 0xc10 },
{ 0xc12, 0xc28 },
{ 0xc2a, 0xc39 },
- { 0xc3d, 0xc3d },
+ { 0xc3d, 0xc44 },
+ { 0xc46, 0xc48 },
+ { 0xc4a, 0xc4c },
+ { 0xc55, 0xc56 },
{ 0xc58, 0xc5a },
{ 0xc5d, 0xc5d },
- { 0xc60, 0xc61 },
- { 0xc80, 0xc80 },
+ { 0xc60, 0xc63 },
+ { 0xc80, 0xc83 },
{ 0xc85, 0xc8c },
{ 0xc8e, 0xc90 },
{ 0xc92, 0xca8 },
{ 0xcaa, 0xcb3 },
{ 0xcb5, 0xcb9 },
- { 0xcbd, 0xcbd },
+ { 0xcbd, 0xcc4 },
+ { 0xcc6, 0xcc8 },
+ { 0xcca, 0xccc },
+ { 0xcd5, 0xcd6 },
{ 0xcdd, 0xcde },
- { 0xce0, 0xce1 },
- { 0xcf1, 0xcf2 },
- { 0xd04, 0xd0c },
+ { 0xce0, 0xce3 },
+ { 0xcf1, 0xcf3 },
+ { 0xd00, 0xd0c },
{ 0xd0e, 0xd10 },
{ 0xd12, 0xd3a },
- { 0xd3d, 0xd3d },
+ { 0xd3d, 0xd44 },
+ { 0xd46, 0xd48 },
+ { 0xd4a, 0xd4c },
{ 0xd4e, 0xd4e },
- { 0xd54, 0xd56 },
- { 0xd5f, 0xd61 },
+ { 0xd54, 0xd57 },
+ { 0xd5f, 0xd63 },
{ 0xd7a, 0xd7f },
+ { 0xd81, 0xd83 },
{ 0xd85, 0xd96 },
{ 0xd9a, 0xdb1 },
{ 0xdb3, 0xdbb },
{ 0xdbd, 0xdbd },
{ 0xdc0, 0xdc6 },
- { 0xe01, 0xe30 },
- { 0xe32, 0xe33 },
+ { 0xdcf, 0xdd4 },
+ { 0xdd6, 0xdd6 },
+ { 0xdd8, 0xddf },
+ { 0xdf2, 0xdf3 },
+ { 0xe01, 0xe3a },
{ 0xe40, 0xe46 },
+ { 0xe4d, 0xe4d },
{ 0xe81, 0xe82 },
{ 0xe84, 0xe84 },
{ 0xe86, 0xe8a },
{ 0xe8c, 0xea3 },
{ 0xea5, 0xea5 },
- { 0xea7, 0xeb0 },
- { 0xeb2, 0xeb3 },
- { 0xebd, 0xebd },
+ { 0xea7, 0xeb9 },
+ { 0xebb, 0xebd },
{ 0xec0, 0xec4 },
{ 0xec6, 0xec6 },
+ { 0xecd, 0xecd },
{ 0xedc, 0xedf },
{ 0xf00, 0xf00 },
{ 0xf40, 0xf47 },
{ 0xf49, 0xf6c },
- { 0xf88, 0xf8c },
- { 0x1000, 0x102a },
- { 0x103f, 0x103f },
- { 0x1050, 0x1055 },
- { 0x105a, 0x105d },
- { 0x1061, 0x1061 },
- { 0x1065, 0x1066 },
- { 0x106e, 0x1070 },
- { 0x1075, 0x1081 },
- { 0x108e, 0x108e },
+ { 0xf71, 0xf83 },
+ { 0xf88, 0xf97 },
+ { 0xf99, 0xfbc },
+ { 0x1000, 0x1036 },
+ { 0x1038, 0x1038 },
+ { 0x103b, 0x103f },
+ { 0x1050, 0x108f },
+ { 0x109a, 0x109d },
{ 0x10a0, 0x10c5 },
{ 0x10c7, 0x10c7 },
{ 0x10cd, 0x10cd },
@@ -2959,37 +3103,44 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x166f, 0x167f },
{ 0x1681, 0x169a },
{ 0x16a0, 0x16ea },
- { 0x16f1, 0x16f8 },
- { 0x1700, 0x1711 },
- { 0x171f, 0x1731 },
- { 0x1740, 0x1751 },
+ { 0x16ee, 0x16f8 },
+ { 0x1700, 0x1713 },
+ { 0x171f, 0x1733 },
+ { 0x1740, 0x1753 },
{ 0x1760, 0x176c },
{ 0x176e, 0x1770 },
+ { 0x1772, 0x1773 },
{ 0x1780, 0x17b3 },
+ { 0x17b6, 0x17c8 },
{ 0x17d7, 0x17d7 },
{ 0x17dc, 0x17dc },
{ 0x1820, 0x1878 },
- { 0x1880, 0x1884 },
- { 0x1887, 0x18a8 },
- { 0x18aa, 0x18aa },
+ { 0x1880, 0x18aa },
{ 0x18b0, 0x18f5 },
{ 0x1900, 0x191e },
+ { 0x1920, 0x192b },
+ { 0x1930, 0x1938 },
{ 0x1950, 0x196d },
{ 0x1970, 0x1974 },
{ 0x1980, 0x19ab },
{ 0x19b0, 0x19c9 },
- { 0x1a00, 0x1a16 },
- { 0x1a20, 0x1a54 },
+ { 0x1a00, 0x1a1b },
+ { 0x1a20, 0x1a5e },
+ { 0x1a61, 0x1a74 },
{ 0x1aa7, 0x1aa7 },
- { 0x1b05, 0x1b33 },
+ { 0x1abf, 0x1ac0 },
+ { 0x1acc, 0x1ace },
+ { 0x1b00, 0x1b33 },
+ { 0x1b35, 0x1b43 },
{ 0x1b45, 0x1b4c },
- { 0x1b83, 0x1ba0 },
- { 0x1bae, 0x1baf },
+ { 0x1b80, 0x1ba9 },
+ { 0x1bac, 0x1baf },
{ 0x1bba, 0x1be5 },
- { 0x1c00, 0x1c23 },
+ { 0x1be7, 0x1bf1 },
+ { 0x1c00, 0x1c36 },
{ 0x1c4d, 0x1c4f },
{ 0x1c5a, 0x1c7d },
- { 0x1c80, 0x1c88 },
+ { 0x1c80, 0x1c8a },
{ 0x1c90, 0x1cba },
{ 0x1cbd, 0x1cbf },
{ 0x1ce9, 0x1cec },
@@ -2997,6 +3148,7 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x1cf5, 0x1cf6 },
{ 0x1cfa, 0x1cfa },
{ 0x1d00, 0x1dbf },
+ { 0x1dd3, 0x1df4 },
{ 0x1e00, 0x1f15 },
{ 0x1f18, 0x1f1d },
{ 0x1f20, 0x1f45 },
@@ -3032,7 +3184,8 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x213c, 0x213f },
{ 0x2145, 0x2149 },
{ 0x214e, 0x214e },
- { 0x2183, 0x2184 },
+ { 0x2160, 0x2188 },
+ { 0x24b6, 0x24e9 },
{ 0x2c00, 0x2ce4 },
{ 0x2ceb, 0x2cee },
{ 0x2cf2, 0x2cf3 },
@@ -3050,10 +3203,12 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x2dc8, 0x2dce },
{ 0x2dd0, 0x2dd6 },
{ 0x2dd8, 0x2dde },
+ { 0x2de0, 0x2dff },
{ 0x2e2f, 0x2e2f },
- { 0x3005, 0x3006 },
+ { 0x3005, 0x3007 },
+ { 0x3021, 0x3029 },
{ 0x3031, 0x3035 },
- { 0x303b, 0x303c },
+ { 0x3038, 0x303c },
{ 0x3041, 0x3096 },
{ 0x309d, 0x309f },
{ 0x30a1, 0x30fa },
@@ -3069,45 +3224,39 @@ inline constexpr CharRange unicode_letter[] = {
{ 0xa610, 0xa61f },
{ 0xa62a, 0xa62b },
{ 0xa640, 0xa66e },
- { 0xa67f, 0xa69d },
- { 0xa6a0, 0xa6e5 },
+ { 0xa674, 0xa67b },
+ { 0xa67f, 0xa6ef },
{ 0xa717, 0xa71f },
{ 0xa722, 0xa788 },
- { 0xa78b, 0xa7ca },
+ { 0xa78b, 0xa7cd },
{ 0xa7d0, 0xa7d1 },
{ 0xa7d3, 0xa7d3 },
- { 0xa7d5, 0xa7d9 },
- { 0xa7f2, 0xa801 },
- { 0xa803, 0xa805 },
- { 0xa807, 0xa80a },
- { 0xa80c, 0xa822 },
+ { 0xa7d5, 0xa7dc },
+ { 0xa7f2, 0xa805 },
+ { 0xa807, 0xa827 },
{ 0xa840, 0xa873 },
- { 0xa882, 0xa8b3 },
+ { 0xa880, 0xa8c3 },
+ { 0xa8c5, 0xa8c5 },
{ 0xa8f2, 0xa8f7 },
{ 0xa8fb, 0xa8fb },
- { 0xa8fd, 0xa8fe },
- { 0xa90a, 0xa925 },
- { 0xa930, 0xa946 },
+ { 0xa8fd, 0xa8ff },
+ { 0xa90a, 0xa92a },
+ { 0xa930, 0xa952 },
{ 0xa960, 0xa97c },
- { 0xa984, 0xa9b2 },
+ { 0xa980, 0xa9b2 },
+ { 0xa9b4, 0xa9bf },
{ 0xa9cf, 0xa9cf },
- { 0xa9e0, 0xa9e4 },
- { 0xa9e6, 0xa9ef },
+ { 0xa9e0, 0xa9ef },
{ 0xa9fa, 0xa9fe },
- { 0xaa00, 0xaa28 },
- { 0xaa40, 0xaa42 },
- { 0xaa44, 0xaa4b },
+ { 0xaa00, 0xaa36 },
+ { 0xaa40, 0xaa4d },
{ 0xaa60, 0xaa76 },
- { 0xaa7a, 0xaa7a },
- { 0xaa7e, 0xaaaf },
- { 0xaab1, 0xaab1 },
- { 0xaab5, 0xaab6 },
- { 0xaab9, 0xaabd },
+ { 0xaa7a, 0xaabe },
{ 0xaac0, 0xaac0 },
{ 0xaac2, 0xaac2 },
{ 0xaadb, 0xaadd },
- { 0xaae0, 0xaaea },
- { 0xaaf2, 0xaaf4 },
+ { 0xaae0, 0xaaef },
+ { 0xaaf2, 0xaaf5 },
{ 0xab01, 0xab06 },
{ 0xab09, 0xab0e },
{ 0xab11, 0xab16 },
@@ -3115,7 +3264,7 @@ inline constexpr CharRange unicode_letter[] = {
{ 0xab28, 0xab2e },
{ 0xab30, 0xab5a },
{ 0xab5c, 0xab69 },
- { 0xab70, 0xabe2 },
+ { 0xab70, 0xabea },
{ 0xac00, 0xd7a3 },
{ 0xd7b0, 0xd7c6 },
{ 0xd7cb, 0xd7fb },
@@ -3123,8 +3272,7 @@ inline constexpr CharRange unicode_letter[] = {
{ 0xfa70, 0xfad9 },
{ 0xfb00, 0xfb06 },
{ 0xfb13, 0xfb17 },
- { 0xfb1d, 0xfb1d },
- { 0xfb1f, 0xfb28 },
+ { 0xfb1d, 0xfb28 },
{ 0xfb2a, 0xfb36 },
{ 0xfb38, 0xfb3c },
{ 0xfb3e, 0xfb3e },
@@ -3151,15 +3299,16 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x1003f, 0x1004d },
{ 0x10050, 0x1005d },
{ 0x10080, 0x100fa },
+ { 0x10140, 0x10174 },
{ 0x10280, 0x1029c },
{ 0x102a0, 0x102d0 },
{ 0x10300, 0x1031f },
- { 0x1032d, 0x10340 },
- { 0x10342, 0x10349 },
- { 0x10350, 0x10375 },
+ { 0x1032d, 0x1034a },
+ { 0x10350, 0x1037a },
{ 0x10380, 0x1039d },
{ 0x103a0, 0x103c3 },
{ 0x103c8, 0x103cf },
+ { 0x103d1, 0x103d5 },
{ 0x10400, 0x1049d },
{ 0x104b0, 0x104d3 },
{ 0x104d8, 0x104fb },
@@ -3173,6 +3322,7 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x105a3, 0x105b1 },
{ 0x105b3, 0x105b9 },
{ 0x105bb, 0x105bc },
+ { 0x105c0, 0x105f3 },
{ 0x10600, 0x10736 },
{ 0x10740, 0x10755 },
{ 0x10760, 0x10767 },
@@ -3193,8 +3343,9 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x10920, 0x10939 },
{ 0x10980, 0x109b7 },
{ 0x109be, 0x109bf },
- { 0x10a00, 0x10a00 },
- { 0x10a10, 0x10a13 },
+ { 0x10a00, 0x10a03 },
+ { 0x10a05, 0x10a06 },
+ { 0x10a0c, 0x10a13 },
{ 0x10a15, 0x10a17 },
{ 0x10a19, 0x10a35 },
{ 0x10a60, 0x10a7c },
@@ -3208,104 +3359,143 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x10c00, 0x10c48 },
{ 0x10c80, 0x10cb2 },
{ 0x10cc0, 0x10cf2 },
- { 0x10d00, 0x10d23 },
+ { 0x10d00, 0x10d27 },
+ { 0x10d4a, 0x10d65 },
+ { 0x10d69, 0x10d69 },
+ { 0x10d6f, 0x10d85 },
{ 0x10e80, 0x10ea9 },
+ { 0x10eab, 0x10eac },
{ 0x10eb0, 0x10eb1 },
+ { 0x10ec2, 0x10ec4 },
+ { 0x10efc, 0x10efc },
{ 0x10f00, 0x10f1c },
{ 0x10f27, 0x10f27 },
{ 0x10f30, 0x10f45 },
{ 0x10f70, 0x10f81 },
{ 0x10fb0, 0x10fc4 },
{ 0x10fe0, 0x10ff6 },
- { 0x11003, 0x11037 },
- { 0x11071, 0x11072 },
- { 0x11075, 0x11075 },
- { 0x11083, 0x110af },
+ { 0x11000, 0x11045 },
+ { 0x11071, 0x11075 },
+ { 0x11080, 0x110b8 },
+ { 0x110c2, 0x110c2 },
{ 0x110d0, 0x110e8 },
- { 0x11103, 0x11126 },
- { 0x11144, 0x11144 },
- { 0x11147, 0x11147 },
+ { 0x11100, 0x11132 },
+ { 0x11144, 0x11147 },
{ 0x11150, 0x11172 },
{ 0x11176, 0x11176 },
- { 0x11183, 0x111b2 },
+ { 0x11180, 0x111bf },
{ 0x111c1, 0x111c4 },
+ { 0x111ce, 0x111cf },
{ 0x111da, 0x111da },
{ 0x111dc, 0x111dc },
{ 0x11200, 0x11211 },
- { 0x11213, 0x1122b },
- { 0x1123f, 0x11240 },
+ { 0x11213, 0x11234 },
+ { 0x11237, 0x11237 },
+ { 0x1123e, 0x11241 },
{ 0x11280, 0x11286 },
{ 0x11288, 0x11288 },
{ 0x1128a, 0x1128d },
{ 0x1128f, 0x1129d },
{ 0x1129f, 0x112a8 },
- { 0x112b0, 0x112de },
+ { 0x112b0, 0x112e8 },
+ { 0x11300, 0x11303 },
{ 0x11305, 0x1130c },
{ 0x1130f, 0x11310 },
{ 0x11313, 0x11328 },
{ 0x1132a, 0x11330 },
{ 0x11332, 0x11333 },
{ 0x11335, 0x11339 },
- { 0x1133d, 0x1133d },
+ { 0x1133d, 0x11344 },
+ { 0x11347, 0x11348 },
+ { 0x1134b, 0x1134c },
{ 0x11350, 0x11350 },
- { 0x1135d, 0x11361 },
- { 0x11400, 0x11434 },
+ { 0x11357, 0x11357 },
+ { 0x1135d, 0x11363 },
+ { 0x11380, 0x11389 },
+ { 0x1138b, 0x1138b },
+ { 0x1138e, 0x1138e },
+ { 0x11390, 0x113b5 },
+ { 0x113b7, 0x113c0 },
+ { 0x113c2, 0x113c2 },
+ { 0x113c5, 0x113c5 },
+ { 0x113c7, 0x113ca },
+ { 0x113cc, 0x113cd },
+ { 0x113d1, 0x113d1 },
+ { 0x113d3, 0x113d3 },
+ { 0x11400, 0x11441 },
+ { 0x11443, 0x11445 },
{ 0x11447, 0x1144a },
{ 0x1145f, 0x11461 },
- { 0x11480, 0x114af },
+ { 0x11480, 0x114c1 },
{ 0x114c4, 0x114c5 },
{ 0x114c7, 0x114c7 },
- { 0x11580, 0x115ae },
- { 0x115d8, 0x115db },
- { 0x11600, 0x1162f },
+ { 0x11580, 0x115b5 },
+ { 0x115b8, 0x115be },
+ { 0x115d8, 0x115dd },
+ { 0x11600, 0x1163e },
+ { 0x11640, 0x11640 },
{ 0x11644, 0x11644 },
- { 0x11680, 0x116aa },
+ { 0x11680, 0x116b5 },
{ 0x116b8, 0x116b8 },
{ 0x11700, 0x1171a },
+ { 0x1171d, 0x1172a },
{ 0x11740, 0x11746 },
- { 0x11800, 0x1182b },
+ { 0x11800, 0x11838 },
{ 0x118a0, 0x118df },
{ 0x118ff, 0x11906 },
{ 0x11909, 0x11909 },
{ 0x1190c, 0x11913 },
{ 0x11915, 0x11916 },
- { 0x11918, 0x1192f },
- { 0x1193f, 0x1193f },
- { 0x11941, 0x11941 },
+ { 0x11918, 0x11935 },
+ { 0x11937, 0x11938 },
+ { 0x1193b, 0x1193c },
+ { 0x1193f, 0x11942 },
{ 0x119a0, 0x119a7 },
- { 0x119aa, 0x119d0 },
+ { 0x119aa, 0x119d7 },
+ { 0x119da, 0x119df },
{ 0x119e1, 0x119e1 },
- { 0x119e3, 0x119e3 },
- { 0x11a00, 0x11a00 },
- { 0x11a0b, 0x11a32 },
- { 0x11a3a, 0x11a3a },
- { 0x11a50, 0x11a50 },
- { 0x11a5c, 0x11a89 },
+ { 0x119e3, 0x119e4 },
+ { 0x11a00, 0x11a32 },
+ { 0x11a35, 0x11a3e },
+ { 0x11a50, 0x11a97 },
{ 0x11a9d, 0x11a9d },
{ 0x11ab0, 0x11af8 },
+ { 0x11bc0, 0x11be0 },
{ 0x11c00, 0x11c08 },
- { 0x11c0a, 0x11c2e },
+ { 0x11c0a, 0x11c36 },
+ { 0x11c38, 0x11c3e },
{ 0x11c40, 0x11c40 },
{ 0x11c72, 0x11c8f },
+ { 0x11c92, 0x11ca7 },
+ { 0x11ca9, 0x11cb6 },
{ 0x11d00, 0x11d06 },
{ 0x11d08, 0x11d09 },
- { 0x11d0b, 0x11d30 },
- { 0x11d46, 0x11d46 },
+ { 0x11d0b, 0x11d36 },
+ { 0x11d3a, 0x11d3a },
+ { 0x11d3c, 0x11d3d },
+ { 0x11d3f, 0x11d41 },
+ { 0x11d43, 0x11d43 },
+ { 0x11d46, 0x11d47 },
{ 0x11d60, 0x11d65 },
{ 0x11d67, 0x11d68 },
- { 0x11d6a, 0x11d89 },
+ { 0x11d6a, 0x11d8e },
+ { 0x11d90, 0x11d91 },
+ { 0x11d93, 0x11d96 },
{ 0x11d98, 0x11d98 },
- { 0x11ee0, 0x11ef2 },
- { 0x11f02, 0x11f02 },
- { 0x11f04, 0x11f10 },
- { 0x11f12, 0x11f33 },
+ { 0x11ee0, 0x11ef6 },
+ { 0x11f00, 0x11f10 },
+ { 0x11f12, 0x11f3a },
+ { 0x11f3e, 0x11f40 },
{ 0x11fb0, 0x11fb0 },
{ 0x12000, 0x12399 },
+ { 0x12400, 0x1246e },
{ 0x12480, 0x12543 },
{ 0x12f90, 0x12ff0 },
{ 0x13000, 0x1342f },
{ 0x13441, 0x13446 },
+ { 0x13460, 0x143fa },
{ 0x14400, 0x14646 },
+ { 0x16100, 0x1612e },
{ 0x16800, 0x16a38 },
{ 0x16a40, 0x16a5e },
{ 0x16a70, 0x16abe },
@@ -3314,15 +3504,17 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x16b40, 0x16b43 },
{ 0x16b63, 0x16b77 },
{ 0x16b7d, 0x16b8f },
+ { 0x16d40, 0x16d6c },
{ 0x16e40, 0x16e7f },
{ 0x16f00, 0x16f4a },
- { 0x16f50, 0x16f50 },
- { 0x16f93, 0x16f9f },
+ { 0x16f4f, 0x16f87 },
+ { 0x16f8f, 0x16f9f },
{ 0x16fe0, 0x16fe1 },
{ 0x16fe3, 0x16fe3 },
+ { 0x16ff0, 0x16ff1 },
{ 0x17000, 0x187f7 },
{ 0x18800, 0x18cd5 },
- { 0x18d00, 0x18d08 },
+ { 0x18cff, 0x18d08 },
{ 0x1aff0, 0x1aff3 },
{ 0x1aff5, 0x1affb },
{ 0x1affd, 0x1affe },
@@ -3336,6 +3528,7 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x1bc70, 0x1bc7c },
{ 0x1bc80, 0x1bc88 },
{ 0x1bc90, 0x1bc99 },
+ { 0x1bc9e, 0x1bc9e },
{ 0x1d400, 0x1d454 },
{ 0x1d456, 0x1d49c },
{ 0x1d49e, 0x1d49f },
@@ -3368,19 +3561,28 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x1d7c4, 0x1d7cb },
{ 0x1df00, 0x1df1e },
{ 0x1df25, 0x1df2a },
+ { 0x1e000, 0x1e006 },
+ { 0x1e008, 0x1e018 },
+ { 0x1e01b, 0x1e021 },
+ { 0x1e023, 0x1e024 },
+ { 0x1e026, 0x1e02a },
{ 0x1e030, 0x1e06d },
+ { 0x1e08f, 0x1e08f },
{ 0x1e100, 0x1e12c },
{ 0x1e137, 0x1e13d },
{ 0x1e14e, 0x1e14e },
{ 0x1e290, 0x1e2ad },
{ 0x1e2c0, 0x1e2eb },
{ 0x1e4d0, 0x1e4eb },
+ { 0x1e5d0, 0x1e5ed },
+ { 0x1e5f0, 0x1e5f0 },
{ 0x1e7e0, 0x1e7e6 },
{ 0x1e7e8, 0x1e7eb },
{ 0x1e7ed, 0x1e7ee },
{ 0x1e7f0, 0x1e7fe },
{ 0x1e800, 0x1e8c4 },
{ 0x1e900, 0x1e943 },
+ { 0x1e947, 0x1e947 },
{ 0x1e94b, 0x1e94b },
{ 0x1ee00, 0x1ee03 },
{ 0x1ee05, 0x1ee1f },
@@ -3415,6 +3617,9 @@ inline constexpr CharRange unicode_letter[] = {
{ 0x1eea1, 0x1eea3 },
{ 0x1eea5, 0x1eea9 },
{ 0x1eeab, 0x1eebb },
+ { 0x1f130, 0x1f149 },
+ { 0x1f150, 0x1f169 },
+ { 0x1f170, 0x1f189 },
{ 0x20000, 0x2a6df },
{ 0x2a700, 0x2b739 },
{ 0x2b740, 0x2b81d },
diff --git a/core/string/char_utils.h b/core/string/char_utils.h
index 9f2e17eb96..63ee3aee4e 100644
--- a/core/string/char_utils.h
+++ b/core/string/char_utils.h
@@ -40,97 +40,97 @@
#define BSEARCH_CHAR_RANGE(m_array) \
int low = 0; \
int high = sizeof(m_array) / sizeof(m_array[0]) - 1; \
- int middle; \
+ int middle = (low + high) / 2; \
\
while (low <= high) { \
- middle = (low + high) / 2; \
- \
- if (c < m_array[middle].start) { \
+ if (p_char < m_array[middle].start) { \
high = middle - 1; \
- } else if (c > m_array[middle].end) { \
+ } else if (p_char > m_array[middle].end) { \
low = middle + 1; \
} else { \
return true; \
} \
+ \
+ middle = (low + high) / 2; \
} \
\
return false
-static _FORCE_INLINE_ bool is_unicode_identifier_start(char32_t c) {
+constexpr bool is_unicode_identifier_start(char32_t p_char) {
BSEARCH_CHAR_RANGE(xid_start);
}
-static _FORCE_INLINE_ bool is_unicode_identifier_continue(char32_t c) {
+constexpr bool is_unicode_identifier_continue(char32_t p_char) {
BSEARCH_CHAR_RANGE(xid_continue);
}
-static _FORCE_INLINE_ bool is_unicode_upper_case(char32_t c) {
+constexpr bool is_unicode_upper_case(char32_t p_char) {
BSEARCH_CHAR_RANGE(uppercase_letter);
}
-static _FORCE_INLINE_ bool is_unicode_lower_case(char32_t c) {
+constexpr bool is_unicode_lower_case(char32_t p_char) {
BSEARCH_CHAR_RANGE(lowercase_letter);
}
-static _FORCE_INLINE_ bool is_unicode_letter(char32_t c) {
+constexpr bool is_unicode_letter(char32_t p_char) {
BSEARCH_CHAR_RANGE(unicode_letter);
}
#undef BSEARCH_CHAR_RANGE
-static _FORCE_INLINE_ bool is_ascii_upper_case(char32_t c) {
- return (c >= 'A' && c <= 'Z');
+constexpr bool is_ascii_upper_case(char32_t p_char) {
+ return (p_char >= 'A' && p_char <= 'Z');
}
-static _FORCE_INLINE_ bool is_ascii_lower_case(char32_t c) {
- return (c >= 'a' && c <= 'z');
+constexpr bool is_ascii_lower_case(char32_t p_char) {
+ return (p_char >= 'a' && p_char <= 'z');
}
-static _FORCE_INLINE_ bool is_digit(char32_t c) {
- return (c >= '0' && c <= '9');
+constexpr bool is_digit(char32_t p_char) {
+ return (p_char >= '0' && p_char <= '9');
}
-static _FORCE_INLINE_ bool is_hex_digit(char32_t c) {
- return (is_digit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+constexpr bool is_hex_digit(char32_t p_char) {
+ return (is_digit(p_char) || (p_char >= 'a' && p_char <= 'f') || (p_char >= 'A' && p_char <= 'F'));
}
-static _FORCE_INLINE_ bool is_binary_digit(char32_t c) {
- return (c == '0' || c == '1');
+constexpr bool is_binary_digit(char32_t p_char) {
+ return (p_char == '0' || p_char == '1');
}
-static _FORCE_INLINE_ bool is_ascii_alphabet_char(char32_t c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+constexpr bool is_ascii_alphabet_char(char32_t p_char) {
+ return (p_char >= 'a' && p_char <= 'z') || (p_char >= 'A' && p_char <= 'Z');
}
-static _FORCE_INLINE_ bool is_ascii_alphanumeric_char(char32_t c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9');
+constexpr bool is_ascii_alphanumeric_char(char32_t p_char) {
+ return (p_char >= 'a' && p_char <= 'z') || (p_char >= 'A' && p_char <= 'Z') || (p_char >= '0' && p_char <= '9');
}
-static _FORCE_INLINE_ bool is_ascii_identifier_char(char32_t c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
+constexpr bool is_ascii_identifier_char(char32_t p_char) {
+ return (p_char >= 'a' && p_char <= 'z') || (p_char >= 'A' && p_char <= 'Z') || (p_char >= '0' && p_char <= '9') || p_char == '_';
}
-static _FORCE_INLINE_ bool is_symbol(char32_t c) {
- return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
+constexpr bool is_symbol(char32_t p_char) {
+ return p_char != '_' && ((p_char >= '!' && p_char <= '/') || (p_char >= ':' && p_char <= '@') || (p_char >= '[' && p_char <= '`') || (p_char >= '{' && p_char <= '~') || p_char == '\t' || p_char == ' ');
}
-static _FORCE_INLINE_ bool is_control(char32_t p_char) {
+constexpr bool is_control(char32_t p_char) {
return (p_char <= 0x001f) || (p_char >= 0x007f && p_char <= 0x009f);
}
-static _FORCE_INLINE_ bool is_whitespace(char32_t p_char) {
+constexpr bool is_whitespace(char32_t p_char) {
return (p_char == ' ') || (p_char == 0x00a0) || (p_char == 0x1680) || (p_char >= 0x2000 && p_char <= 0x200a) || (p_char == 0x202f) || (p_char == 0x205f) || (p_char == 0x3000) || (p_char == 0x2028) || (p_char == 0x2029) || (p_char >= 0x0009 && p_char <= 0x000d) || (p_char == 0x0085);
}
-static _FORCE_INLINE_ bool is_linebreak(char32_t p_char) {
+constexpr bool is_linebreak(char32_t p_char) {
return (p_char >= 0x000a && p_char <= 0x000d) || (p_char == 0x0085) || (p_char == 0x2028) || (p_char == 0x2029);
}
-static _FORCE_INLINE_ bool is_punct(char32_t p_char) {
+constexpr bool is_punct(char32_t p_char) {
return (p_char >= ' ' && p_char <= '/') || (p_char >= ':' && p_char <= '@') || (p_char >= '[' && p_char <= '^') || (p_char == '`') || (p_char >= '{' && p_char <= '~') || (p_char >= 0x2000 && p_char <= 0x206f) || (p_char >= 0x3000 && p_char <= 0x303f);
}
-static _FORCE_INLINE_ bool is_underscore(char32_t p_char) {
+constexpr bool is_underscore(char32_t p_char) {
return (p_char == '_');
}
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index b126da0646..73ffe14e50 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1852,6 +1852,8 @@ String String::num(double p_num, int p_decimals) {
}
String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
+ ERR_FAIL_COND_V_MSG(base < 2 || base > 36, "", "Cannot convert to base " + itos(base) + ", since the value is " + (base < 2 ? "less than 2." : "greater than 36."));
+
bool sign = p_num < 0;
int64_t n = p_num;
@@ -1890,6 +1892,8 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
}
String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
+ ERR_FAIL_COND_V_MSG(base < 2 || base > 36, "", "Cannot convert to base " + itos(base) + ", since the value is " + (base < 2 ? "less than 2." : "greater than 36."));
+
uint64_t n = p_num;
int chars = 0;
diff --git a/core/templates/a_hash_map.cpp b/core/templates/a_hash_map.cpp
new file mode 100644
index 0000000000..ebb0373924
--- /dev/null
+++ b/core/templates/a_hash_map.cpp
@@ -0,0 +1,41 @@
+/**************************************************************************/
+/* a_hash_map.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2024-present Redot Engine contributors */
+/* (see REDOT_AUTHORS.md) */
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "a_hash_map.h"
+#include "core/variant/variant.h"
+
+// Explicit instantiation.
+template class AHashMap<int, int>;
+template class AHashMap<String, int>;
+template class AHashMap<StringName, StringName>;
+template class AHashMap<StringName, Variant>;
+template class AHashMap<StringName, int>;
diff --git a/core/templates/a_hash_map.h b/core/templates/a_hash_map.h
new file mode 100644
index 0000000000..d390b3af0d
--- /dev/null
+++ b/core/templates/a_hash_map.h
@@ -0,0 +1,734 @@
+/**************************************************************************/
+/* a_hash_map.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2024-present Redot Engine contributors */
+/* (see REDOT_AUTHORS.md) */
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef A_HASH_MAP_H
+#define A_HASH_MAP_H
+
+#include "core/templates/hash_map.h"
+
+struct HashMapData {
+ union {
+ struct
+ {
+ uint32_t hash;
+ uint32_t hash_to_key;
+ };
+ uint64_t data;
+ };
+};
+
+static_assert(sizeof(HashMapData) == 8);
+
+/**
+ * An array-based implementation of a hash map. It is very efficient in terms of performance and
+ * memory usage. Works like a dynamic array, adding elements to the end of the array, and
+ * allows you to access array elements by their index by using `get_by_index` method.
+ * Example:
+ * ```
+ * AHashMap<int, Object *> map;
+ *
+ * int get_object_id_by_number(int p_number) {
+ * int id = map.get_index(p_number);
+ * return id;
+ * }
+ *
+ * Object *get_object_by_id(int p_id) {
+ * map.get_by_index(p_id).value;
+ * }
+ * ```
+ * Still, don`t erase the elements because ID can break.
+ *
+ * When an element erase, its place is taken by the element from the end.
+ *
+ * <-------------
+ * | |
+ * 6 8 X 9 32 -1 5 -10 7 X X X
+ * 6 8 7 9 32 -1 5 -10 X X X X
+ *
+ *
+ * Use RBMap if you need to iterate over sorted elements.
+ *
+ * Use HashMap if:
+ * - You need to keep an iterator or const pointer to Key and you intend to add/remove elements in the meantime.
+ * - You need to preserve the insertion order when using erase.
+ *
+ * It is recommended to use `HashMap` if `KeyValue` size is very large.
+ */
+template <typename TKey, typename TValue,
+ typename Hasher = HashMapHasherDefault,
+ typename Comparator = HashMapComparatorDefault<TKey>>
+class AHashMap {
+public:
+ // Must be a power of two.
+ static constexpr uint32_t INITIAL_CAPACITY = 16;
+ static constexpr uint32_t EMPTY_HASH = 0;
+ static_assert(EMPTY_HASH == 0, "EMPTY_HASH must always be 0 for the memcpy() optimization.");
+
+private:
+ typedef KeyValue<TKey, TValue> MapKeyValue;
+ MapKeyValue *elements = nullptr;
+ HashMapData *map_data = nullptr;
+
+ // Due to optimization, this is `capacity - 1`. Use + 1 to get normal capacity.
+ uint32_t capacity = 0;
+ uint32_t num_elements = 0;
+
+ uint32_t _hash(const TKey &p_key) const {
+ uint32_t hash = Hasher::hash(p_key);
+
+ if (unlikely(hash == EMPTY_HASH)) {
+ hash = EMPTY_HASH + 1;
+ }
+
+ return hash;
+ }
+
+ static _FORCE_INLINE_ uint32_t _get_resize_count(uint32_t p_capacity) {
+ return p_capacity ^ (p_capacity + 1) >> 2; // = get_capacity() * 0.75 - 1; Works only if p_capacity = 2^n - 1.
+ }
+
+ static _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash, uint32_t p_local_capacity) {
+ const uint32_t original_pos = p_hash & p_local_capacity;
+ return (p_pos - original_pos + p_local_capacity + 1) & p_local_capacity;
+ }
+
+ bool _lookup_pos(const TKey &p_key, uint32_t &r_pos, uint32_t &r_hash_pos) const {
+ if (unlikely(elements == nullptr)) {
+ return false; // Failed lookups, no elements.
+ }
+ return _lookup_pos_with_hash(p_key, r_pos, r_hash_pos, _hash(p_key));
+ }
+
+ bool _lookup_pos_with_hash(const TKey &p_key, uint32_t &r_pos, uint32_t &r_hash_pos, uint32_t p_hash) const {
+ if (unlikely(elements == nullptr)) {
+ return false; // Failed lookups, no elements.
+ }
+
+ uint32_t pos = p_hash & capacity;
+ HashMapData data = map_data[pos];
+ if (data.hash == p_hash && Comparator::compare(elements[data.hash_to_key].key, p_key)) {
+ r_pos = data.hash_to_key;
+ r_hash_pos = pos;
+ return true;
+ }
+
+ if (data.data == EMPTY_HASH) {
+ return false;
+ }
+
+ // A collision occurred.
+ pos = (pos + 1) & capacity;
+ uint32_t distance = 1;
+ while (true) {
+ data = map_data[pos];
+ if (data.hash == p_hash && Comparator::compare(elements[data.hash_to_key].key, p_key)) {
+ r_pos = data.hash_to_key;
+ r_hash_pos = pos;
+ return true;
+ }
+
+ if (data.data == EMPTY_HASH) {
+ return false;
+ }
+
+ if (distance > _get_probe_length(pos, data.hash, capacity)) {
+ return false;
+ }
+
+ pos = (pos + 1) & capacity;
+ distance++;
+ }
+ }
+
+ uint32_t _insert_with_hash(uint32_t p_hash, uint32_t p_index) {
+ uint32_t pos = p_hash & capacity;
+
+ if (map_data[pos].data == EMPTY_HASH) {
+ uint64_t data = ((uint64_t)p_index << 32) | p_hash;
+ map_data[pos].data = data;
+ return pos;
+ }
+
+ uint32_t distance = 1;
+ pos = (pos + 1) & capacity;
+ HashMapData c_data;
+ c_data.hash = p_hash;
+ c_data.hash_to_key = p_index;
+
+ while (true) {
+ if (map_data[pos].data == EMPTY_HASH) {
+#ifdef DEV_ENABLED
+ if (unlikely(distance > 12)) {
+ WARN_PRINT("Excessive collision count (" +
+ itos(distance) + "), is the right hash function being used?");
+ }
+#endif
+ map_data[pos] = c_data;
+ return pos;
+ }
+
+ // Not an empty slot, let's check the probing length of the existing one.
+ uint32_t existing_probe_len = _get_probe_length(pos, map_data[pos].hash, capacity);
+ if (existing_probe_len < distance) {
+ SWAP(c_data, map_data[pos]);
+ distance = existing_probe_len;
+ }
+
+ pos = (pos + 1) & capacity;
+ distance++;
+ }
+ }
+
+ void _resize_and_rehash(uint32_t p_new_capacity) {
+ uint32_t real_old_capacity = capacity + 1;
+ // Capacity can't be 0 and must be 2^n - 1.
+ capacity = MAX(4u, p_new_capacity);
+ uint32_t real_capacity = next_power_of_2(capacity);
+ capacity = real_capacity - 1;
+
+ HashMapData *old_map_data = map_data;
+
+ map_data = reinterpret_cast<HashMapData *>(Memory::alloc_static(sizeof(HashMapData) * real_capacity));
+ elements = reinterpret_cast<MapKeyValue *>(Memory::realloc_static(elements, sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1)));
+
+ memset(map_data, EMPTY_HASH, real_capacity * sizeof(HashMapData));
+
+ if (num_elements != 0) {
+ for (uint32_t i = 0; i < real_old_capacity; i++) {
+ HashMapData data = old_map_data[i];
+ if (data.data != EMPTY_HASH) {
+ _insert_with_hash(data.hash, data.hash_to_key);
+ }
+ }
+ }
+
+ Memory::free_static(old_map_data);
+ }
+
+ int32_t _insert_element(const TKey &p_key, const TValue &p_value, uint32_t p_hash) {
+ if (unlikely(elements == nullptr)) {
+ // Allocate on demand to save memory.
+
+ uint32_t real_capacity = capacity + 1;
+ map_data = reinterpret_cast<HashMapData *>(Memory::alloc_static(sizeof(HashMapData) * real_capacity));
+ elements = reinterpret_cast<MapKeyValue *>(Memory::alloc_static(sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1)));
+
+ memset(map_data, EMPTY_HASH, real_capacity * sizeof(HashMapData));
+ }
+
+ if (unlikely(num_elements > _get_resize_count(capacity))) {
+ _resize_and_rehash(capacity * 2);
+ }
+
+ memnew_placement(&elements[num_elements], MapKeyValue(p_key, p_value));
+
+ _insert_with_hash(p_hash, num_elements);
+ num_elements++;
+ return num_elements - 1;
+ }
+
+ void _init_from(const AHashMap &p_other) {
+ capacity = p_other.capacity;
+ uint32_t real_capacity = capacity + 1;
+ num_elements = p_other.num_elements;
+
+ if (p_other.num_elements == 0) {
+ return;
+ }
+
+ map_data = reinterpret_cast<HashMapData *>(Memory::alloc_static(sizeof(HashMapData) * real_capacity));
+ elements = reinterpret_cast<MapKeyValue *>(Memory::alloc_static(sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1)));
+
+ if constexpr (std::is_trivially_copyable_v<TKey> && std::is_trivially_copyable_v<TValue>) {
+ void *destination = elements;
+ const void *source = p_other.elements;
+ memcpy(destination, source, sizeof(MapKeyValue) * num_elements);
+ } else {
+ for (uint32_t i = 0; i < num_elements; i++) {
+ memnew_placement(&elements[i], MapKeyValue(p_other.elements[i]));
+ }
+ }
+
+ memcpy(map_data, p_other.map_data, sizeof(HashMapData) * real_capacity);
+ }
+
+public:
+ /* Standard Godot Container API */
+
+ _FORCE_INLINE_ uint32_t get_capacity() const { return capacity + 1; }
+ _FORCE_INLINE_ uint32_t size() const { return num_elements; }
+
+ _FORCE_INLINE_ bool is_empty() const {
+ return num_elements == 0;
+ }
+
+ void clear() {
+ if (elements == nullptr || num_elements == 0) {
+ return;
+ }
+
+ memset(map_data, EMPTY_HASH, (capacity + 1) * sizeof(HashMapData));
+ if constexpr (!(std::is_trivially_destructible_v<TKey> && std::is_trivially_destructible_v<TValue>)) {
+ for (uint32_t i = 0; i < num_elements; i++) {
+ elements[i].key.~TKey();
+ elements[i].value.~TValue();
+ }
+ }
+
+ num_elements = 0;
+ }
+
+ TValue &get(const TKey &p_key) {
+ uint32_t pos = 0;
+ uint32_t hash_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, hash_pos);
+ CRASH_COND_MSG(!exists, "AHashMap key not found.");
+ return elements[pos].value;
+ }
+
+ const TValue &get(const TKey &p_key) const {
+ uint32_t pos = 0;
+ uint32_t hash_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, hash_pos);
+ CRASH_COND_MSG(!exists, "AHashMap key not found.");
+ return elements[pos].value;
+ }
+
+ const TValue *getptr(const TKey &p_key) const {
+ uint32_t pos = 0;
+ uint32_t hash_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, hash_pos);
+
+ if (exists) {
+ return &elements[pos].value;
+ }
+ return nullptr;
+ }
+
+ TValue *getptr(const TKey &p_key) {
+ uint32_t pos = 0;
+ uint32_t hash_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, hash_pos);
+
+ if (exists) {
+ return &elements[pos].value;
+ }
+ return nullptr;
+ }
+
+ bool has(const TKey &p_key) const {
+ uint32_t _pos = 0;
+ uint32_t h_pos = 0;
+ return _lookup_pos(p_key, _pos, h_pos);
+ }
+
+ bool erase(const TKey &p_key) {
+ uint32_t pos = 0;
+ uint32_t element_pos = 0;
+ bool exists = _lookup_pos(p_key, element_pos, pos);
+
+ if (!exists) {
+ return false;
+ }
+
+ uint32_t next_pos = (pos + 1) & capacity;
+ while (map_data[next_pos].hash != EMPTY_HASH && _get_probe_length(next_pos, map_data[next_pos].hash, capacity) != 0) {
+ SWAP(map_data[next_pos], map_data[pos]);
+
+ pos = next_pos;
+ next_pos = (next_pos + 1) & capacity;
+ }
+
+ map_data[pos].data = EMPTY_HASH;
+ elements[element_pos].key.~TKey();
+ elements[element_pos].value.~TValue();
+ num_elements--;
+
+ if (element_pos < num_elements) {
+ void *destination = &elements[element_pos];
+ const void *source = &elements[num_elements];
+ memcpy(destination, source, sizeof(MapKeyValue));
+ uint32_t h_pos = 0;
+ _lookup_pos(elements[num_elements].key, pos, h_pos);
+ map_data[h_pos].hash_to_key = element_pos;
+ }
+
+ return true;
+ }
+
+ // Replace the key of an entry in-place, without invalidating iterators or changing the entries position during iteration.
+ // p_old_key must exist in the map and p_new_key must not, unless it is equal to p_old_key.
+ bool replace_key(const TKey &p_old_key, const TKey &p_new_key) {
+ if (p_old_key == p_new_key) {
+ return true;
+ }
+ uint32_t pos = 0;
+ uint32_t element_pos = 0;
+ ERR_FAIL_COND_V(_lookup_pos(p_new_key, element_pos, pos), false);
+ ERR_FAIL_COND_V(!_lookup_pos(p_old_key, element_pos, pos), false);
+ MapKeyValue &element = elements[element_pos];
+ const_cast<TKey &>(element.key) = p_new_key;
+
+ uint32_t next_pos = (pos + 1) & capacity;
+ while (map_data[next_pos].hash != EMPTY_HASH && _get_probe_length(next_pos, map_data[next_pos].hash, capacity) != 0) {
+ SWAP(map_data[next_pos], map_data[pos]);
+
+ pos = next_pos;
+ next_pos = (next_pos + 1) & capacity;
+ }
+
+ map_data[pos].data = EMPTY_HASH;
+
+ uint32_t hash = _hash(p_new_key);
+ _insert_with_hash(hash, element_pos);
+
+ return true;
+ }
+
+ // Reserves space for a number of elements, useful to avoid many resizes and rehashes.
+ // If adding a known (possibly large) number of elements at once, must be larger than old capacity.
+ void reserve(uint32_t p_new_capacity) {
+ ERR_FAIL_COND_MSG(p_new_capacity < get_capacity(), "It is impossible to reserve less capacity than is currently available.");
+ if (elements == nullptr) {
+ capacity = MAX(4u, p_new_capacity);
+ capacity = next_power_of_2(capacity) - 1;
+ return; // Unallocated yet.
+ }
+ _resize_and_rehash(p_new_capacity);
+ }
+
+ /** Iterator API **/
+
+ struct ConstIterator {
+ _FORCE_INLINE_ const MapKeyValue &operator*() const {
+ return *pair;
+ }
+ _FORCE_INLINE_ const MapKeyValue *operator->() const {
+ return pair;
+ }
+ _FORCE_INLINE_ ConstIterator &operator++() {
+ pair++;
+ return *this;
+ }
+
+ _FORCE_INLINE_ ConstIterator &operator--() {
+ pair--;
+ if (pair < begin) {
+ pair = end;
+ }
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return pair == b.pair; }
+ _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return pair != b.pair; }
+
+ _FORCE_INLINE_ explicit operator bool() const {
+ return pair != end;
+ }
+
+ _FORCE_INLINE_ ConstIterator(MapKeyValue *p_key, MapKeyValue *p_begin, MapKeyValue *p_end) {
+ pair = p_key;
+ begin = p_begin;
+ end = p_end;
+ }
+ _FORCE_INLINE_ ConstIterator() {}
+ _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) {
+ pair = p_it.pair;
+ begin = p_it.begin;
+ end = p_it.end;
+ }
+ _FORCE_INLINE_ void operator=(const ConstIterator &p_it) {
+ pair = p_it.pair;
+ begin = p_it.begin;
+ end = p_it.end;
+ }
+
+ private:
+ MapKeyValue *pair = nullptr;
+ MapKeyValue *begin = nullptr;
+ MapKeyValue *end = nullptr;
+ };
+
+ struct Iterator {
+ _FORCE_INLINE_ MapKeyValue &operator*() const {
+ return *pair;
+ }
+ _FORCE_INLINE_ MapKeyValue *operator->() const {
+ return pair;
+ }
+ _FORCE_INLINE_ Iterator &operator++() {
+ pair++;
+ return *this;
+ }
+ _FORCE_INLINE_ Iterator &operator--() {
+ pair--;
+ if (pair < begin) {
+ pair = end;
+ }
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return pair == b.pair; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return pair != b.pair; }
+
+ _FORCE_INLINE_ explicit operator bool() const {
+ return pair != end;
+ }
+
+ _FORCE_INLINE_ Iterator(MapKeyValue *p_key, MapKeyValue *p_begin, MapKeyValue *p_end) {
+ pair = p_key;
+ begin = p_begin;
+ end = p_end;
+ }
+ _FORCE_INLINE_ Iterator() {}
+ _FORCE_INLINE_ Iterator(const Iterator &p_it) {
+ pair = p_it.pair;
+ begin = p_it.begin;
+ end = p_it.end;
+ }
+ _FORCE_INLINE_ void operator=(const Iterator &p_it) {
+ pair = p_it.pair;
+ begin = p_it.begin;
+ end = p_it.end;
+ }
+
+ operator ConstIterator() const {
+ return ConstIterator(pair, begin, end);
+ }
+
+ private:
+ MapKeyValue *pair = nullptr;
+ MapKeyValue *begin = nullptr;
+ MapKeyValue *end = nullptr;
+ };
+
+ _FORCE_INLINE_ Iterator begin() {
+ return Iterator(elements, elements, elements + num_elements);
+ }
+ _FORCE_INLINE_ Iterator end() {
+ return Iterator(elements + num_elements, elements, elements + num_elements);
+ }
+ _FORCE_INLINE_ Iterator last() {
+ if (unlikely(num_elements == 0)) {
+ return Iterator(nullptr, nullptr, nullptr);
+ }
+ return Iterator(elements + num_elements - 1, elements, elements + num_elements);
+ }
+
+ Iterator find(const TKey &p_key) {
+ uint32_t pos = 0;
+ uint32_t h_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, h_pos);
+ if (!exists) {
+ return end();
+ }
+ return Iterator(elements + pos, elements, elements + num_elements);
+ }
+
+ void remove(const Iterator &p_iter) {
+ if (p_iter) {
+ erase(p_iter->key);
+ }
+ }
+
+ _FORCE_INLINE_ ConstIterator begin() const {
+ return ConstIterator(elements, elements, elements + num_elements);
+ }
+ _FORCE_INLINE_ ConstIterator end() const {
+ return ConstIterator(elements + num_elements, elements, elements + num_elements);
+ }
+ _FORCE_INLINE_ ConstIterator last() const {
+ if (unlikely(num_elements == 0)) {
+ return ConstIterator(nullptr, nullptr, nullptr);
+ }
+ return ConstIterator(elements + num_elements - 1, elements, elements + num_elements);
+ }
+
+ ConstIterator find(const TKey &p_key) const {
+ uint32_t pos = 0;
+ uint32_t h_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, h_pos);
+ if (!exists) {
+ return end();
+ }
+ return ConstIterator(elements + pos, elements, elements + num_elements);
+ }
+
+ /* Indexing */
+
+ const TValue &operator[](const TKey &p_key) const {
+ uint32_t pos = 0;
+ uint32_t h_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, h_pos);
+ CRASH_COND(!exists);
+ return elements[pos].value;
+ }
+
+ TValue &operator[](const TKey &p_key) {
+ uint32_t pos = 0;
+ uint32_t h_pos = 0;
+ uint32_t hash = _hash(p_key);
+ bool exists = _lookup_pos_with_hash(p_key, pos, h_pos, hash);
+
+ if (exists) {
+ return elements[pos].value;
+ } else {
+ pos = _insert_element(p_key, TValue(), hash);
+ return elements[pos].value;
+ }
+ }
+
+ /* Insert */
+
+ Iterator insert(const TKey &p_key, const TValue &p_value) {
+ uint32_t pos = 0;
+ uint32_t h_pos = 0;
+ uint32_t hash = _hash(p_key);
+ bool exists = _lookup_pos_with_hash(p_key, pos, h_pos, hash);
+
+ if (!exists) {
+ pos = _insert_element(p_key, p_value, hash);
+ } else {
+ elements[pos].value = p_value;
+ }
+ return Iterator(elements + pos, elements, elements + num_elements);
+ }
+
+ // Inserts an element without checking if it already exists.
+ void insert_new(const TKey &p_key, const TValue &p_value) {
+ DEV_ASSERT(!has(p_key));
+ uint32_t hash = _hash(p_key);
+ _insert_element(p_key, p_value, hash);
+ }
+
+ /* Array methods. */
+
+ // Unsafe. Changing keys and going outside the bounds of an array can lead to undefined behavior.
+ KeyValue<TKey, TValue> *get_elements_ptr() {
+ return elements;
+ }
+
+ // Returns the element index. If not found, returns -1.
+ int get_index(const TKey &p_key) {
+ uint32_t pos = 0;
+ uint32_t h_pos = 0;
+ bool exists = _lookup_pos(p_key, pos, h_pos);
+ if (!exists) {
+ return -1;
+ }
+ return pos;
+ }
+
+ KeyValue<TKey, TValue> &get_by_index(uint32_t p_index) {
+ CRASH_BAD_UNSIGNED_INDEX(p_index, num_elements);
+ return elements[p_index];
+ }
+
+ bool erase_by_index(uint32_t p_index) {
+ if (p_index >= size()) {
+ return false;
+ }
+ return erase(elements[p_index].key);
+ }
+
+ /* Constructors */
+
+ AHashMap(const AHashMap &p_other) {
+ _init_from(p_other);
+ }
+
+ AHashMap(const HashMap<TKey, TValue> &p_other) {
+ reserve(p_other.size());
+ for (const KeyValue<TKey, TValue> &E : p_other) {
+ uint32_t hash = _hash(E.key);
+ _insert_element(E.key, E.value, hash);
+ }
+ }
+
+ void operator=(const AHashMap &p_other) {
+ if (this == &p_other) {
+ return; // Ignore self assignment.
+ }
+
+ reset();
+
+ _init_from(p_other);
+ }
+
+ void operator=(const HashMap<TKey, TValue> &p_other) {
+ reset();
+ if (p_other.size() > get_capacity()) {
+ reserve(p_other.size());
+ }
+ for (const KeyValue<TKey, TValue> &E : p_other) {
+ uint32_t hash = _hash(E.key);
+ _insert_element(E.key, E.value, hash);
+ }
+ }
+
+ AHashMap(uint32_t p_initial_capacity) {
+ // Capacity can't be 0 and must be 2^n - 1.
+ capacity = MAX(4u, p_initial_capacity);
+ capacity = next_power_of_2(capacity) - 1;
+ }
+ AHashMap() :
+ capacity(INITIAL_CAPACITY - 1) {
+ }
+
+ void reset() {
+ if (elements != nullptr) {
+ if constexpr (!(std::is_trivially_destructible_v<TKey> && std::is_trivially_destructible_v<TValue>)) {
+ for (uint32_t i = 0; i < num_elements; i++) {
+ elements[i].key.~TKey();
+ elements[i].value.~TValue();
+ }
+ }
+ Memory::free_static(elements);
+ Memory::free_static(map_data);
+ elements = nullptr;
+ }
+ capacity = INITIAL_CAPACITY - 1;
+ num_elements = 0;
+ }
+
+ ~AHashMap() {
+ reset();
+ }
+};
+
+extern template class AHashMap<int, int>;
+extern template class AHashMap<String, int>;
+extern template class AHashMap<StringName, StringName>;
+extern template class AHashMap<StringName, Variant>;
+extern template class AHashMap<StringName, int>;
+
+#endif // A_HASH_MAP_H
diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h
index 32fcf31ea9..1406ec327b 100644
--- a/core/templates/hashfuncs.h
+++ b/core/templates/hashfuncs.h
@@ -395,6 +395,13 @@ struct HashMapHasherDefault {
}
};
+struct HashHasher {
+ static _FORCE_INLINE_ uint32_t hash(const int32_t hash) { return hash; }
+ static _FORCE_INLINE_ uint32_t hash(const uint32_t hash) { return hash; }
+ static _FORCE_INLINE_ uint64_t hash(const int64_t hash) { return hash; }
+ static _FORCE_INLINE_ uint64_t hash(const uint64_t hash) { return hash; }
+};
+
// TODO: Fold this into HashMapHasherDefault once C++20 concepts are allowed
template <typename T>
struct HashableHasher {
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index 62b9755777..08d7d8230f 100644
--- a/core/variant/variant_op.cpp
+++ b/core/variant/variant_op.cpp
@@ -982,6 +982,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<NodePath>>(Variant::OP_IN, Variant::NODE_PATH, Variant::DICTIONARY);
+ register_op<OperatorEvaluatorInDictionaryHas<::RID>>(Variant::OP_IN, Variant::RID, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHasObject>(Variant::OP_IN, Variant::OBJECT, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Callable>>(Variant::OP_IN, Variant::CALLABLE, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Signal>>(Variant::OP_IN, Variant::SIGNAL, Variant::DICTIONARY);
@@ -1023,6 +1024,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<NodePath, Array>>(Variant::OP_IN, Variant::NODE_PATH, Variant::ARRAY);
+ register_op<OperatorEvaluatorInArrayFind<::RID, Array>>(Variant::OP_IN, Variant::RID, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFindObject>(Variant::OP_IN, Variant::OBJECT, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Callable, Array>>(Variant::OP_IN, Variant::CALLABLE, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Signal, Array>>(Variant::OP_IN, Variant::SIGNAL, Variant::ARRAY);