Skip to content

Commit

Permalink
Add String::concat and string.extend functions, for string concat…
Browse files Browse the repository at this point in the history
…enations where the contributors to the final string are well-known at the time of call.
  • Loading branch information
Ivorforce committed Jan 4, 2025
1 parent bdf625b commit 4009044
Show file tree
Hide file tree
Showing 19 changed files with 156 additions and 30 deletions.
5 changes: 4 additions & 1 deletion core/math/aabb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,5 +445,8 @@ Variant AABB::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) c
}

AABB::operator String() const {
return "[P: " + position.operator String() + ", S: " + size + "]";
return String::concat(
"[P: ", position.operator String(),
", S: ", size,
"]");
}
8 changes: 5 additions & 3 deletions core/math/basis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,9 +715,11 @@ bool Basis::operator!=(const Basis &p_matrix) const {
}

Basis::operator String() const {
return "[X: " + get_column(0).operator String() +
", Y: " + get_column(1).operator String() +
", Z: " + get_column(2).operator String() + "]";
return String::concat(
"[X: ", get_column(0).operator String(),
", Y: ", get_column(1).operator String(),
", Z: ", get_column(2).operator String(),
"]");
}

Quaternion Basis::get_quaternion() const {
Expand Down
8 changes: 7 additions & 1 deletion core/math/color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,13 @@ Color Color::from_rgba8(int64_t p_r8, int64_t p_g8, int64_t p_b8, int64_t p_a8)
}

Color::operator String() const {
return "(" + String::num(r, 4) + ", " + String::num(g, 4) + ", " + String::num(b, 4) + ", " + String::num(a, 4) + ")";
return String::concat(
"(",
String::num(r, 4), ", ",
String::num(g, 4), ", ",
String::num(b, 4), ", ",
String::num(a, 4),
")");
}

Color Color::operator+(const Color &p_color) const {
Expand Down
5 changes: 4 additions & 1 deletion core/math/face3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const {
}

Face3::operator String() const {
return String() + vertex[0] + ", " + vertex[1] + ", " + vertex[2];
return String::concat(
vertex[0], ", ",
vertex[1], ", ",
vertex[2]);
}

void Face3::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const {
Expand Down
5 changes: 4 additions & 1 deletion core/math/plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,8 @@ bool Plane::is_finite() const {
}

Plane::operator String() const {
return "[N: " + normal.operator String() + ", D: " + String::num_real(d, false) + "]";
return String::concat(
"[N: ", normal.operator String(),
", D: ", String::num_real(d, false),
"]");
}
10 changes: 6 additions & 4 deletions core/math/projection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,10 +912,12 @@ void Projection::set_light_atlas_rect(const Rect2 &p_rect) {
}

Projection::operator String() const {
return "[X: " + columns[0].operator String() +
", Y: " + columns[1].operator String() +
", Z: " + columns[2].operator String() +
", W: " + columns[3].operator String() + "]";
return String::concat(
"[X: ", columns[0].operator String(),
", Y: ", columns[1].operator String(),
", Z: ", columns[2].operator String(),
", W: ", columns[3].operator String(),
"]");
}

real_t Projection::get_aspect() const {
Expand Down
10 changes: 8 additions & 2 deletions core/math/quaternion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,13 @@ Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b
}

Quaternion::operator String() const {
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
return String::concat(
"(",
String::num_real(x, false), ", ",
String::num_real(y, false), ", ",
String::num_real(z, false), ", ",
String::num_real(w, false),
")");
}

Vector3 Quaternion::get_axis() const {
Expand All @@ -294,7 +300,7 @@ real_t Quaternion::get_angle() const {

Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) {
#ifdef MATH_CHECKS
ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 " + p_axis.operator String() + " must be normalized.");
ERR_FAIL_COND_MSG(!p_axis.is_normalized(), String::concat("The axis Vector3 ", p_axis.operator String(), " must be normalized."));
#endif
real_t d = p_axis.length();
if (d == 0) {
Expand Down
5 changes: 4 additions & 1 deletion core/math/rect2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,10 @@ bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_re
}

Rect2::operator String() const {
return "[P: " + position.operator String() + ", S: " + size.operator String() + "]";
return String::concat(
"[P: ", position.operator String(),
", S: ", size.operator String(),
"]");
}

Rect2::operator Rect2i() const {
Expand Down
5 changes: 4 additions & 1 deletion core/math/rect2i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
#include "core/string/ustring.h"

Rect2i::operator String() const {
return "[P: " + position.operator String() + ", S: " + size + "]";
return String::concat(
"[P: ", position.operator String(),
", S: ", size,
"]");
}

Rect2i::operator Rect2() const {
Expand Down
8 changes: 5 additions & 3 deletions core/math/transform_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ Transform2D Transform2D::operator/(real_t p_val) const {
}

Transform2D::operator String() const {
return "[X: " + columns[0].operator String() +
", Y: " + columns[1].operator String() +
", O: " + columns[2].operator String() + "]";
return String::concat(
"[X: ", columns[0].operator String(),
", Y: ", columns[1].operator String(),
", O: ", columns[2].operator String(),
"]");
}
10 changes: 6 additions & 4 deletions core/math/transform_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,12 @@ Transform3D Transform3D::operator/(real_t p_val) const {
}

Transform3D::operator String() const {
return "[X: " + basis.get_column(0).operator String() +
", Y: " + basis.get_column(1).operator String() +
", Z: " + basis.get_column(2).operator String() +
", O: " + origin.operator String() + "]";
return String::concat(
"[X: ", basis.get_column(0).operator String(),
", Y: ", basis.get_column(1).operator String(),
", Z: ", basis.get_column(2).operator String(),
", O: ", origin.operator String(),
"]");
}

Transform3D::Transform3D(const Basis &p_basis, const Vector3 &p_origin) :
Expand Down
6 changes: 5 additions & 1 deletion core/math/vector2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ bool Vector2::is_finite() const {
}

Vector2::operator String() const {
return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ")";
return String::concat(
"(",
String::num_real(x, true), ", ",
String::num_real(y, true),
")");
}

Vector2::operator Vector2i() const {
Expand Down
6 changes: 5 additions & 1 deletion core/math/vector2i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ bool Vector2i::operator!=(const Vector2i &p_vec2) const {
}

Vector2i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ")";
return String::concat(
"(",
itos(x), ", ",
itos(y),
")");
}

Vector2i::operator Vector2() const {
Expand Down
7 changes: 6 additions & 1 deletion core/math/vector3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,12 @@ bool Vector3::is_finite() const {
}

Vector3::operator String() const {
return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ", " + String::num_real(z, true) + ")";
return String::concat(
"(",
String::num_real(x, true), ", ",
String::num_real(y, true), ", ",
String::num_real(z, true),
")");
}

Vector3::operator Vector3i() const {
Expand Down
7 changes: 6 additions & 1 deletion core/math/vector3i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ Vector3i Vector3i::snappedi(int32_t p_step) const {
}

Vector3i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
return String::concat(
"(",
itos(x), ", ",
itos(y), ", ",
itos(z),
")");
}

Vector3i::operator Vector3() const {
Expand Down
8 changes: 7 additions & 1 deletion core/math/vector4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,13 @@ Vector4 Vector4::clampf(real_t p_min, real_t p_max) const {
}

Vector4::operator String() const {
return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ", " + String::num_real(z, true) + ", " + String::num_real(w, true) + ")";
return String::concat(
"(",
String::num_real(x, true), ", ",
String::num_real(y, true), ", ",
String::num_real(z, true), ", ",
String::num_real(w, true),
")");
}

static_assert(sizeof(Vector4) == 4 * sizeof(real_t));
Expand Down
8 changes: 7 additions & 1 deletion core/math/vector4i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,13 @@ Vector4i Vector4i::snappedi(int32_t p_step) const {
}

Vector4i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
return String::concat(
"(",
itos(x), ", ",
itos(y), ", ",
itos(z), ", ",
itos(w),
")");
}

Vector4i::operator Vector4() const {
Expand Down
61 changes: 61 additions & 0 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,23 @@ class String {
// Use `is_valid_ascii_identifier()` instead. Kept for compatibility.
bool is_valid_identifier() const { return is_valid_ascii_identifier(); }

template <typename... Args>
void extend(Args... args);

template <typename... Args>
static String concat(Args... args) {
String string;
string.extend(args...);
return string;
}

template <typename... Args>
static String concat(String &&string, Args... args) {
// Optimized case of the concat call, where we can consume the first argument to avoid re-allocation.
string.extend(args...);
return std::move(string);
}

/**
* The constructors must not depend on other overloads
*/
Expand Down Expand Up @@ -654,6 +671,50 @@ String operator+(const char *p_chr, const String &p_str);
String operator+(const wchar_t *p_chr, const String &p_str);
String operator+(char32_t p_chr, const String &p_str);

_FORCE_INLINE_ char32_t *_insert_string(const StrRange<char> &string, char32_t *dst) {
const char32_t *src = dst;
for (const char32_t *end = dst + string.len; src < end; ++src, ++dst) {
*dst = *src;
}
return dst;
}

_FORCE_INLINE_ char32_t *_insert_string(const StrRange<char32_t> &string, char32_t *dst) {
memcpy(dst, string.c_str, string.len * sizeof(char32_t));
dst += string.len;
return dst;
}

inline StrRange<char32_t> _to_str_range(const String &string) {
return StrRange<char32_t>(string);
}
template <typename Char, typename = std::enable_if_t<std::is_fundamental_v<Char>>>
StrRange<Char> _to_str_range(const StrRange<Char> &string) {
return string;
}
template <typename Char, size_t len, typename = std::enable_if_t<std::is_fundamental_v<Char>>>
StrRange<Char> _to_str_range(const Char (&string)[len]) {
return StrRange<Char>::from_c_str(string);
}
template <typename Char, typename = std::enable_if_t<std::is_fundamental_v<Char>>>
StrRange<Char> _to_str_range(const Char &chr) {
return StrRange<Char>(&chr, 1);
}

template <typename... Args>
void _extend_string_ranges(String &string, Args... args) {
const int length_before = string.length();
string.resize(length_before + (args.len + ...) + 1);
char32_t *dst = string.ptrw() + length_before;
((dst = _insert_string(args, dst)), ...);
*dst = 0;
}

template <typename... Args>
void String::extend(Args... args) {
_extend_string_ranges(*this, _to_str_range(args)...);
}

String itos(int64_t p_val);
String uitos(uint64_t p_val);
String rtos(double p_val);
Expand Down
4 changes: 2 additions & 2 deletions core/variant/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1875,10 +1875,10 @@ String Variant::stringify(int recursion_count) const {
}
case RID: {
const ::RID &s = *reinterpret_cast<const ::RID *>(_data._mem);
return "RID(" + itos(s.get_id()) + ")";
return String::concat("RID(", itos(s.get_id()), ")");
}
default: {
return "<" + get_type_name(type) + ">";
return String::concat("<", get_type_name(type), ">");
}
}
}
Expand Down

0 comments on commit 4009044

Please sign in to comment.