Fix AABB's build.

This commit is contained in:
Relintai 2023-12-18 22:36:56 +01:00
parent 36aa30a296
commit 76a4ac5535
11 changed files with 569 additions and 37 deletions

View File

@ -407,6 +407,7 @@ void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
}
}
/*
Variant AABB::intersects_segmentv(const Vector3 &p_from, const Vector3 &p_to) const {
Vector3 inters;
if (intersects_segment(p_from, p_to, &inters)) {
@ -422,6 +423,7 @@ Variant AABB::intersects_rayv(const Vector3 &p_from, const Vector3 &p_dir) const
}
return Variant();
}
*/
AABB::operator String() const {
return "[P: " + position.operator String() + ", S: " + size + "]";

View File

@ -41,8 +41,6 @@
* This is implemented by a point (position) and the box size
*/
class Variant;
struct _NO_DISCARD_CLASS_ AABB {
Vector3 position;
Vector3 size;
@ -106,8 +104,8 @@ struct _NO_DISCARD_CLASS_ AABB {
return AABB(Vector3(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0), position.z + MIN(size.z, 0)), size.abs());
}
Variant intersects_segmentv(const Vector3 &p_from, const Vector3 &p_to) const;
Variant intersects_rayv(const Vector3 &p_from, const Vector3 &p_dir) const;
//Variant intersects_segmentv(const Vector3 &p_from, const Vector3 &p_to) const;
//Variant intersects_rayv(const Vector3 &p_from, const Vector3 &p_dir) const;
_FORCE_INLINE_ void quantize(real_t p_unit);
_FORCE_INLINE_ AABB quantized(real_t p_unit) const;

View File

@ -34,6 +34,7 @@
#include <string.h>
#include "error_list.h"
#include "error_macros.h"
#include "memory.h"
#include "safe_refcount.h"

View File

@ -65,40 +65,43 @@ _FORCE_INLINE_ void _RLOG_MACRO_TEMPLATE_FUNC(STR str, A p0, B p1, C p2, D p3, E
str->append(p4);
}
#define RPRINT_TRACE(str) \
#define PRINT_TRACE(str) \
RLogger::print_trace(__FUNCTION__, __FILE__, __LINE__, str);
#define RLOG_TRACE(...) \
#define LOG_TRACE(...) \
{ \
String *_rlogger_string_ptr = RLogger::get_trace_string_ptr(__FUNCTION__, __FILE__, __LINE__); \
_RLOG_MACRO_TEMPLATE_FUNC(_rlogger_string_ptr, __VA_ARGS__); \
RLogger::log_ret_ptr(_rlogger_string_ptr); \
}
#define RPRINT_MSG(str) \
#define PRINT_MSG(str) \
RLogger::print_message(__FUNCTION__, __FILE__, __LINE__, str);
#define RLOG_MSG(...) \
#define LOG_MSG(...) \
{ \
String *_rlogger_string_ptr = RLogger::get_message_string_ptr(__FUNCTION__, __FILE__, __LINE__); \
_RLOG_MACRO_TEMPLATE_FUNC(_rlogger_string_ptr, __VA_ARGS__); \
RLogger::log_ret_ptr(_rlogger_string_ptr); \
}
#define RPRINT_WARN(str) \
#define PRINT_WARN(str) \
RLogger::print_warning(__FUNCTION__, __FILE__, __LINE__, str);
#define RLOG_WARN(...) \
#define LOG_WARN(...) \
{ \
String *_rlogger_string_ptr = RLogger::get_warning_string_ptr(__FUNCTION__, __FILE__, __LINE__); \
_RLOG_MACRO_TEMPLATE_FUNC(_rlogger_string_ptr, __VA_ARGS__); \
RLogger::log_ret_ptr(_rlogger_string_ptr); \
}
#define RPRINT_ERR(str) \
#define PRINT_ERR(str) \
RLogger::print_error(__FUNCTION__, __FILE__, __LINE__, str);
#define RLOG_ERR(...) \
#define ERR_PRINT(str) \
RLogger::print_error(__FUNCTION__, __FILE__, __LINE__, str);
#define LOG_ERR(...) \
{ \
String *_rlogger_string_ptr = RLogger::get_error_string_ptr(__FUNCTION__, __FILE__, __LINE__); \
_RLOG_MACRO_TEMPLATE_FUNC(_rlogger_string_ptr, __VA_ARGS__); \
@ -109,6 +112,10 @@ _FORCE_INLINE_ void _RLOG_MACRO_TEMPLATE_FUNC(STR str, A p0, B p1, C p2, D p3, E
RLogger::log_error(__FUNCTION__, __FILE__, __LINE__, msg); \
return;
#define ERR_FAIL_V(val) \
RLogger::log_error(__FUNCTION__, __FILE__, __LINE__, ""); \
return val;
#define ERR_FAIL_V_MSG(val, msg) \
RLogger::log_error(__FUNCTION__, __FILE__, __LINE__, msg); \
return val;
@ -206,6 +213,20 @@ _FORCE_INLINE_ void _RLOG_MACRO_TEMPLATE_FUNC(STR str, A p0, B p1, C p2, D p3, E
} else \
((void)0)
#define CRASH_BAD_INDEX(index, size) \
if ((index < 0) || (index >= size)) { \
RLogger::log_index_error(__FUNCTION__, __FILE__, __LINE__, index, size, "CRASH!"); \
GENERATE_TRAP \
} else \
((void)0)
#define CRASH_BAD_UNSIGNED_INDEX(index, size) \
if ((index < 0) || (index >= size)) { \
RLogger::log_index_error(__FUNCTION__, __FILE__, __LINE__, index, size, "CRASH!"); \
GENERATE_TRAP \
} else \
((void)0)
#define CRASH_COND(cond) \
if (cond) { \
RLogger::log_error(__FUNCTION__, __FILE__, __LINE__, "CRASH_COND: \"" #cond "\" is true!"); \
@ -213,4 +234,44 @@ _FORCE_INLINE_ void _RLOG_MACRO_TEMPLATE_FUNC(STR str, A p0, B p1, C p2, D p3, E
} else \
((void)0)
/**
* This should be a 'free' assert for program flow and should not be needed in any releases,
* only used in dev builds.
*/
#ifdef DEV_ENABLED
#define DEV_ASSERT(m_cond) \
if (unlikely(!(m_cond))) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: DEV_ASSERT failed \"" _STR(m_cond) "\" is false."); \
_err_flush_stdout(); \
GENERATE_TRAP \
} else \
((void)0)
#else
#define DEV_ASSERT(m_cond)
#endif
/**
* These should be 'free' checks for program flow and should not be needed in any releases,
* only used in dev builds.
*/
#ifdef DEV_ENABLED
#define DEV_CHECK(m_cond) \
if (unlikely(!(m_cond))) { \
ERR_PRINT("DEV_CHECK failed \"" _STR(m_cond) "\" is false."); \
} else \
((void)0)
#else
#define DEV_CHECK(m_cond)
#endif
#ifdef DEV_ENABLED
#define DEV_CHECK_ONCE(m_cond) \
if (unlikely(!(m_cond))) { \
ERR_PRINT_ONCE("DEV_CHECK_ONCE failed \"" _STR(m_cond) "\" is false."); \
} else \
((void)0)
#else
#define DEV_CHECK_ONCE(m_cond)
#endif
#endif

202
sfw/memory.cpp Normal file
View File

@ -0,0 +1,202 @@
/*************************************************************************/
/* memory.cpp */
/*************************************************************************/
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://github.com/Relintai/pandemonium_engine */
/*************************************************************************/
/* Copyright (c) 2022-present Péter Magyar. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2022 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 "memory.h"
#include "core/error/error_macros.h"
#include "core/os/safe_refcount.h"
#include <stdio.h>
#include <stdlib.h>
void *operator new(size_t p_size, const char *p_description) {
return Memory::alloc_static(p_size, false);
}
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
return p_allocfunc(p_size);
}
#ifdef _MSC_VER
void operator delete(void *p_mem, const char *p_description) {
CRASH_NOW_MSG("Call to placement delete should not happen.");
}
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) {
CRASH_NOW_MSG("Call to placement delete should not happen.");
}
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) {
CRASH_NOW_MSG("Call to placement delete should not happen.");
}
#endif
#ifdef DEBUG_ENABLED
SafeNumeric<uint64_t> Memory::mem_usage;
SafeNumeric<uint64_t> Memory::max_usage;
#endif
SafeNumeric<uint64_t> Memory::alloc_count;
void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
#ifdef DEBUG_ENABLED
bool prepad = true;
#else
bool prepad = p_pad_align;
#endif
void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0));
ERR_FAIL_COND_V(!mem, nullptr);
alloc_count.increment();
if (prepad) {
uint64_t *s = (uint64_t *)mem;
*s = p_bytes;
uint8_t *s8 = (uint8_t *)mem;
#ifdef DEBUG_ENABLED
uint64_t new_mem_usage = mem_usage.add(p_bytes);
max_usage.exchange_if_greater(new_mem_usage);
#endif
return s8 + PAD_ALIGN;
} else {
return mem;
}
}
void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
if (p_memory == nullptr) {
return alloc_static(p_bytes, p_pad_align);
}
uint8_t *mem = (uint8_t *)p_memory;
#ifdef DEBUG_ENABLED
bool prepad = true;
#else
bool prepad = p_pad_align;
#endif
if (prepad) {
mem -= PAD_ALIGN;
uint64_t *s = (uint64_t *)mem;
#ifdef DEBUG_ENABLED
if (p_bytes > *s) {
uint64_t new_mem_usage = mem_usage.add(p_bytes - *s);
max_usage.exchange_if_greater(new_mem_usage);
} else {
mem_usage.sub(*s - p_bytes);
}
#endif
if (p_bytes == 0) {
free(mem);
return nullptr;
} else {
*s = p_bytes;
mem = (uint8_t *)realloc(mem, p_bytes + PAD_ALIGN);
ERR_FAIL_COND_V(!mem, nullptr);
s = (uint64_t *)mem;
*s = p_bytes;
return mem + PAD_ALIGN;
}
} else {
mem = (uint8_t *)realloc(mem, p_bytes);
ERR_FAIL_COND_V(mem == nullptr && p_bytes > 0, nullptr);
return mem;
}
}
void Memory::free_static(void *p_ptr, bool p_pad_align) {
ERR_FAIL_COND(p_ptr == nullptr);
uint8_t *mem = (uint8_t *)p_ptr;
#ifdef DEBUG_ENABLED
bool prepad = true;
#else
bool prepad = p_pad_align;
#endif
alloc_count.decrement();
if (prepad) {
mem -= PAD_ALIGN;
#ifdef DEBUG_ENABLED
uint64_t *s = (uint64_t *)mem;
mem_usage.sub(*s);
#endif
free(mem);
} else {
free(mem);
}
}
uint64_t Memory::get_mem_available() {
return -1; // 0xFFFF...
}
uint64_t Memory::get_mem_usage() {
#ifdef DEBUG_ENABLED
return mem_usage.get();
#else
return 0;
#endif
}
uint64_t Memory::get_mem_max_usage() {
#ifdef DEBUG_ENABLED
return max_usage.get();
#else
return 0;
#endif
}
_GlobalNil::_GlobalNil() {
color = 1;
left = this;
right = this;
parent = this;
}
_GlobalNil _GlobalNilClass::_nil;

View File

@ -1,14 +1,206 @@
#ifndef MEMORY_H
#define MEMORY_H
//Simple memnew and memdelete macros so stuff that I took from the godotengine can use it.
//Not yet sure whether to use their allocator or not.
//This will be here until I decide.
/*************************************************************************/
/* memory.h */
/*************************************************************************/
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://github.com/Relintai/pandemonium_engine */
/*************************************************************************/
/* Copyright (c) 2022-present Péter Magyar. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2022 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. */
/*************************************************************************/
#define memnew(m_class) new m_class
#define memdelete(instance) delete instance
#define memnew_arr(m_class, size) new m_class[size]
#define memdelete_arr(instance) delete[] instance
#include "error_macros.h"
#include "safe_refcount.h"
#include <stddef.h>
#ifndef PAD_ALIGN
#define PAD_ALIGN 16 //must always be greater than this at much
#endif
class Memory {
#ifdef DEBUG_ENABLED
static SafeNumeric<uint64_t> mem_usage;
static SafeNumeric<uint64_t> max_usage;
#endif
static SafeNumeric<uint64_t> alloc_count;
public:
static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
static void free_static(void *p_ptr, bool p_pad_align = false);
static uint64_t get_mem_available();
static uint64_t get_mem_usage();
static uint64_t get_mem_max_usage();
};
class DefaultAllocator {
public:
_FORCE_INLINE_ static void *alloc(size_t p_memory) { return Memory::alloc_static(p_memory, false); }
_FORCE_INLINE_ static void free(void *p_ptr) { Memory::free_static(p_ptr, false); }
};
void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
#ifdef _MSC_VER
// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
void operator delete(void *p_mem, const char *p_description);
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size));
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description);
#endif
#define memalloc(m_size) Memory::alloc_static(m_size)
#define memrealloc(m_mem, m_size) Memory::realloc_static(m_mem, m_size)
#define memfree(m_mem) Memory::free_static(m_mem)
_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
template <class T>
_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
postinitialize_handler(p_obj);
return p_obj;
}
#define memnew(m_class) _post_initialize(new ("") m_class)
_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) {
//void *failptr=0;
//ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */
return p_pointer;
}
#define memnew_allocator(m_class, m_allocator) _post_initialize(new (m_allocator::alloc) m_class)
#define memnew_placement(m_placement, m_class) _post_initialize(new (m_placement, sizeof(m_class), "") m_class)
_ALWAYS_INLINE_ bool predelete_handler(void *) {
return true;
}
template <class T>
void memdelete(T *p_class) {
if (!predelete_handler(p_class)) {
return; // doesn't want to be deleted
}
if (!HAS_TRIVIAL_DESTRUCTOR(T)) {
p_class->~T();
}
Memory::free_static(p_class, false);
}
template <class T, class A>
void memdelete_allocator(T *p_class) {
if (!predelete_handler(p_class)) {
return; // doesn't want to be deleted
}
if (!HAS_TRIVIAL_DESTRUCTOR(T)) {
p_class->~T();
}
A::free(p_class);
}
#define memdelete_notnull(m_v) \
{ \
if (m_v) \
memdelete(m_v); \
}
#define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count)
template <typename T>
T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
if (p_elements == 0) {
return nullptr;
}
/** overloading operator new[] cannot be done , because it may not return the real allocated address (it may pad the 'element count' before the actual array). Because of that, it must be done by hand. This is the
same strategy used by std::vector, and the PoolVector class, so it should be safe.*/
size_t len = sizeof(T) * p_elements;
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
T *failptr = nullptr; //get rid of a warning
ERR_FAIL_COND_V(!mem, failptr);
*(mem - 1) = p_elements;
if (!HAS_TRIVIAL_CONSTRUCTOR(T)) {
T *elems = (T *)mem;
/* call operator new */
for (size_t i = 0; i < p_elements; i++) {
new (&elems[i], sizeof(T), p_descr) T;
}
}
return (T *)mem;
}
/**
* Wonders of having own array functions, you can actually check the length of
* an allocated-with memnew_arr() array
*/
template <typename T>
size_t memarr_len(const T *p_class) {
uint64_t *ptr = (uint64_t *)p_class;
return *(ptr - 1);
}
template <typename T>
void memdelete_arr(T *p_class) {
uint64_t *ptr = (uint64_t *)p_class;
if (!HAS_TRIVIAL_DESTRUCTOR(T)) {
uint64_t elem_count = *(ptr - 1);
for (uint64_t i = 0; i < elem_count; i++) {
p_class[i].~T();
}
}
Memory::free_static(ptr, true);
}
struct _GlobalNil {
int color;
_GlobalNil *right;
_GlobalNil *left;
_GlobalNil *parent;
_GlobalNil();
};
struct _GlobalNilClass {
static _GlobalNil _nil;
};
#endif

View File

@ -34,8 +34,6 @@
#include "vector3.h"
class Variant;
struct _NO_DISCARD_CLASS_ Plane {
Vector3 normal;
real_t d;

View File

@ -32,7 +32,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "core/typedefs.h"
#include "typedefs.h"
#if !defined(NO_THREADS)

View File

@ -1,12 +1,16 @@
#ifndef TYPEDEFS_H
#define TYPEDEFS_H
/*************************************************************************/
/* typedefs.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://github.com/Relintai/pandemonium_engine */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2022-present Péter Magyar. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2022 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 */
@ -28,9 +32,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TYPEDEFS_H
#define TYPEDEFS_H
#include <stddef.h>
/**
@ -59,10 +60,9 @@
#endif
//should always inline, except in some cases because it makes debugging harder
// Should always inline, except in dev builds because it makes debugging harder.
#ifndef _FORCE_INLINE_
#ifdef DISABLE_FORCED_INLINE
#ifdef DEV_ENABLED
#define _FORCE_INLINE_ inline
#else
#define _FORCE_INLINE_ _ALWAYS_INLINE_
@ -70,6 +70,47 @@
#endif
// No discard allows the compiler to flag warnings if we don't use the return value of functions / classes
#ifndef _NO_DISCARD_
// c++ 17 onwards
#if __cplusplus >= 201703L
#define _NO_DISCARD_ [[nodiscard]]
#else
// __warn_unused_result__ supported on clang and GCC
#if (defined(__clang__) || defined(__GNUC__)) && defined(__has_attribute)
#if __has_attribute(__warn_unused_result__)
#define _NO_DISCARD_ __attribute__((__warn_unused_result__))
#endif
#endif
// Visual Studio 2012 onwards
#if _MSC_VER >= 1700
#define _NO_DISCARD_ _Check_return_
#endif
// If nothing supported, just noop the macro
#ifndef _NO_DISCARD_
#define _NO_DISCARD_
#endif
#endif // not c++ 17
#endif // not defined _NO_DISCARD_
// In some cases _NO_DISCARD_ will get false positives,
// we can prevent the warning in specific cases by preceding the call with a cast.
#ifndef _ALLOW_DISCARD_
#define _ALLOW_DISCARD_ (void)
#endif
// GCC (prior to c++ 17) Does not seem to support no discard with classes, only functions.
// So we will use a specific macro for classes.
#ifndef _NO_DISCARD_CLASS_
#if (defined(__clang__) || defined(_MSC_VER))
#define _NO_DISCARD_CLASS_ _NO_DISCARD_
#else
#define _NO_DISCARD_CLASS_
#endif
#endif
//custom, gcc-safe offsetof, because gcc complains a lot.
template <class T>
T *_nullptr() {
@ -107,7 +148,7 @@ T *_nullptr() {
#include "int_types.h"
//#include "error_list.h"
#include "error_list.h"
/** Generic ABS function, for math uses please use Math::abs */
@ -118,7 +159,7 @@ T *_nullptr() {
#define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
#ifndef SGN
#define SGN(m_v) (((m_v) < 0) ? (-1.0) : (+1.0))
#define SGN(m_v) (((m_v) < 0) ? (-1.0f) : (+1.0f))
#endif
#ifndef MIN
@ -351,4 +392,37 @@ struct _GlobalLock {
#define FALLTHROUGH
#endif
// Limit the depth of recursive algorithms when dealing with Array/Dictionary
#define MAX_RECURSION 100
//HAS_TRIVIAL_CONSTRUCTOR
#if defined(__llvm__) && _llvm_has_builtin(__is_trivially_constructible)
#define HAS_TRIVIAL_CONSTRUCTOR(T) __is_trivially_constructible(T)
#endif
#ifndef HAS_TRIVIAL_CONSTRUCTOR
#define HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
#endif
//HAS_TRIVIAL_DESTRUCTOR
#if defined(__llvm__) && _llvm_has_builtin(__is_trivially_destructible)
#define HAS_TRIVIAL_DESTRUCTOR(T) __is_trivially_destructible(T)
#endif
#ifndef HAS_TRIVIAL_DESTRUCTOR
#define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
#endif
//HAS_TRIVIAL_COPY
#if defined(__llvm__) && _llvm_has_builtin(__is_trivially_copyable)
#define HAS_TRIVIAL_COPY(T) __is_trivially_copyable(T)
#endif
#ifndef HAS_TRIVIAL_COPY
#define HAS_TRIVIAL_COPY(T) __has_trivial_copy(T)
#endif
#endif // TYPEDEFS_H

View File

@ -1405,6 +1405,7 @@ float String::similarity(const String &p_string) const {
return (2.0f * inter) / sum;
}
/*
String String::format(const Variant &values, String placeholder) const {
String new_string = String(this->ptr());
@ -1456,6 +1457,7 @@ String String::format(const Variant &values, String placeholder) const {
return new_string;
}
*/
String String::replace_first(const String &p_key, const String &p_with) const {
int pos = find(p_key);
@ -1678,6 +1680,7 @@ String String::rpad(int min_length, const String &character) const {
// "fish %s pie" % "frog"
// "fish %s %d pie" % ["frog", 12]
// In case of an error, the string returned is the error description and "error" is true.
/*
String String::sprintf(const Array &values, bool *error) const {
String formatted;
CharType *self = (CharType *)get_data();
@ -1964,6 +1967,7 @@ String String::sprintf(const Array &values, bool *error) const {
}
return formatted;
}
*/
String String::quote(String quotechar) const {
return quotechar + *this + quotechar;

View File

@ -321,7 +321,7 @@ public:
Vector<String> bigrams() const;
float similarity(const String &p_string) const;
String format(const Variant &values, String placeholder = "{_}") const;
//String format(const Variant &values, String placeholder = "{_}") const;
String replace_first(const String &p_key, const String &p_with) const;
String replace(const String &p_key, const String &p_with) const;
@ -342,7 +342,7 @@ public:
String lpad(int min_length, const String &character = " ") const;
String rpad(int min_length, const String &character = " ") const;
String sprintf(const Array &values, bool *error) const;
//String sprintf(const Array &values, bool *error) const;
String quote(String quotechar = "\"") const;
String unquote() const;