fx: implement updated interfaces in builtin classes

This commit is contained in:
2026-05-25 17:27:14 +01:00
parent 5d0aa577d6
commit 6efe473c11
13 changed files with 691 additions and 293 deletions
+142 -45
View File
@@ -1,9 +1,18 @@
#include "cstr.h"
#include <ctype.h>
#include <fx/comparable.h>
#include <fx/convertible.h>
#include <fx/cstr.h>
#include <fx/hash.h>
#include <fx/operable.h>
#include <fx/reflection/function.h>
#include <fx/reflection/property.h>
#include <fx/stream.h>
#include <fx/string.h>
#include <fx/stringstream.h>
#include <fx/value.h>
#include <fx/wstr.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
@@ -1157,23 +1166,6 @@ static fx_string *string_substr(
return newstr;
}
static uint64_t string_hash(const struct fx_string_p *str)
{
#define FNV1_OFFSET_BASIS 0xcbf29ce484222325
#define FNV1_PRIME 0x100000001b3
uint64_t hash = FNV1_OFFSET_BASIS;
size_t i = 0;
const char *s = string_ptr(str);
for (i = 0; i < str->s_len; i++) {
hash ^= s[i];
hash *= FNV1_PRIME;
}
return hash;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_string *fx_string_create_from_cstr(const char *s)
@@ -1471,11 +1463,6 @@ fx_string *fx_string_get_substr(const fx_string *str, size_t start, size_t len)
len);
}
uint64_t fx_string_hash(const fx_string *str)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_STRING, string_hash, str);
}
/*** PUBLIC ALIAS FUNCTIONS ***************************************************/
enum fx_status fx_string_append_c(fx_string *dest, char c)
@@ -1547,13 +1534,54 @@ static void string_fini(fx_object *obj, void *priv)
}
}
static void string_to_string(const fx_object *obj, fx_stream *out)
static fx_status string_to_string(
const fx_value *obj,
fx_stream *out,
const char *format)
{
struct fx_string_p *str = fx_object_get_private(obj, FX_TYPE_STRING);
struct fx_string_p *str = fx_object_get_private(
obj->v_object,
FX_TYPE_STRING);
const char *s = string_ptr(str);
for (size_t i = 0; i < str->s_len; i++) {
fx_stream_write_char(out, s[i]);
}
return FX_SUCCESS;
}
static fx_status string_hash(const fx_value *v, uint64_t *out_hash)
{
struct fx_string_p *str = fx_object_get_private(
v->v_object,
FX_TYPE_STRING);
const char *s = string_ptr(str);
*out_hash = fx_hash_cstr(s);
return FX_SUCCESS;
}
static i32 compare(const fx_value *left, const fx_value *right)
{
const char *left_cstr, *right_cstr;
if (!FX_OK(fx_value_get_cstr(left, &left_cstr))) {
return -1;
}
if (!FX_OK(fx_value_get_cstr(right, &right_cstr))) {
return -1;
}
return strcmp(left_cstr, right_cstr);
}
static fx_status get_length(
const fx_value *str_v,
const fx_property *prop,
fx_value *out)
{
fx_string *str = NULL;
fx_value_get_object(str_v, &str);
*out = FX_SIZE(fx_string_get_size(str, FX_STRLEN_CODEPOINTS));
return FX_SUCCESS;
}
/*** ITERATOR FUNCTIONS *******************************************************/
@@ -1662,19 +1690,17 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
}
}
static fx_iterator_value chars_iterator_get_value(
struct fx_string_iterator_p *it)
static fx_value chars_iterator_get_value(struct fx_string_iterator_p *it)
{
return FX_ITERATOR_VALUE_INT(it->char_value);
return FX_U32(it->char_value);
}
static fx_iterator_value tokens_iterator_get_value(
struct fx_string_iterator_p *it)
static fx_value tokens_iterator_get_value(struct fx_string_iterator_p *it)
{
return FX_ITERATOR_VALUE_CPTR(it->string_value);
return FX_CSTR(it->string_value);
}
static fx_iterator_value iterator_get_value(fx_iterator *obj)
static fx_value iterator_get_value(const fx_iterator *obj)
{
struct fx_string_iterator_p *it = fx_object_get_private(
obj,
@@ -1686,32 +1712,65 @@ static fx_iterator_value iterator_get_value(fx_iterator *obj)
case ITERATOR_MODE_TOKENS:
return tokens_iterator_get_value(it);
default:
return FX_ITERATOR_VALUE_NULL;
return FX_VALUE_EMPTY;
}
}
static const fx_iterator_value iterator_get_cvalue(const fx_iterator *obj)
static fx_status add(const fx_value *l, const fx_value *r, fx_value *out)
{
struct fx_string_iterator_p *it = fx_object_get_private(
obj,
FX_TYPE_STRING_ITERATOR);
switch (it->_m) {
case ITERATOR_MODE_CHARS:
return chars_iterator_get_value(it);
case ITERATOR_MODE_TOKENS:
return tokens_iterator_get_value(it);
default:
return FX_ITERATOR_VALUE_NULL;
fx_string *left = l->v_object;
fx_string *right = r->v_object;
fx_string *result = fx_string_create_from_cstr(
fx_string_get_cstr(left));
if (!result) {
return FX_ERR_NO_MEMORY;
}
fx_string_append_cstr(result, fx_string_get_cstr(right));
*out = FX_VALUE_OBJECT(result);
return FX_SUCCESS;
}
#define STRING_CONVERTER(fx_type, c_type) \
static fx_status to_##fx_type(const fx_value *in, c_type *out) \
{ \
const char *s = NULL; \
fx_value_get_cstr(in, &s); \
return cstr_to_##fx_type(s, out); \
}
STRING_CONVERTER(bool, bool)
STRING_CONVERTER(i16, i16)
STRING_CONVERTER(u16, u16)
STRING_CONVERTER(i32, i32)
STRING_CONVERTER(u32, u32)
STRING_CONVERTER(i64, i64)
STRING_CONVERTER(u64, u64)
STRING_CONVERTER(iptr, iptr)
STRING_CONVERTER(uptr, uptr)
STRING_CONVERTER(sbyte, sbyte)
STRING_CONVERTER(byte, byte)
STRING_CONVERTER(short, short)
STRING_CONVERTER(ushort, unsigned short)
STRING_CONVERTER(int, int)
STRING_CONVERTER(uint, unsigned int)
STRING_CONVERTER(long, long)
STRING_CONVERTER(ulong, unsigned long)
STRING_CONVERTER(longlong, long long)
STRING_CONVERTER(ulonglong, unsigned long long)
STRING_CONVERTER(size, size_t)
STRING_CONVERTER(float, float)
STRING_CONVERTER(double, double)
STRING_CONVERTER(cstr, const char *)
/*** CLASS DEFINITION *********************************************************/
// ---- fx_string DEFINITION
FX_TYPE_CLASS_BEGIN(fx_string)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = string_to_string;
FX_INTERFACE_ENTRY(hash) = string_hash;
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
@@ -1719,6 +1778,40 @@ FX_TYPE_CLASS_BEGIN(fx_string)
FX_INTERFACE_ENTRY(it_cbegin) = iterator_cbegin;
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_operable, FX_TYPE_OPERABLE)
FX_INTERFACE_ENTRY(op_add) = add;
FX_TYPE_VTABLE_INTERFACE_END(fx_operable, FX_TYPE_OPERABLE)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_convertible, FX_TYPE_CONVERTIBLE)
FX_INTERFACE_ENTRY(c_to_bool) = to_bool;
FX_INTERFACE_ENTRY(c_to_bool) = to_bool;
FX_INTERFACE_ENTRY(c_to_i16) = to_i16;
FX_INTERFACE_ENTRY(c_to_u16) = to_u16;
FX_INTERFACE_ENTRY(c_to_u32) = to_u32;
FX_INTERFACE_ENTRY(c_to_i64) = to_i64;
FX_INTERFACE_ENTRY(c_to_u64) = to_u64;
FX_INTERFACE_ENTRY(c_to_iptr) = to_iptr;
FX_INTERFACE_ENTRY(c_to_uptr) = to_uptr;
FX_INTERFACE_ENTRY(c_to_sbyte) = to_sbyte;
FX_INTERFACE_ENTRY(c_to_byte) = to_byte;
FX_INTERFACE_ENTRY(c_to_short) = to_short;
FX_INTERFACE_ENTRY(c_to_ushort) = to_ushort;
FX_INTERFACE_ENTRY(c_to_int) = to_int;
FX_INTERFACE_ENTRY(c_to_uint) = to_uint;
FX_INTERFACE_ENTRY(c_to_long) = to_long;
FX_INTERFACE_ENTRY(c_to_ulong) = to_ulong;
FX_INTERFACE_ENTRY(c_to_longlong) = to_longlong;
FX_INTERFACE_ENTRY(c_to_ulonglong) = to_ulonglong;
FX_INTERFACE_ENTRY(c_to_size) = to_size;
FX_INTERFACE_ENTRY(c_to_float) = to_float;
FX_INTERFACE_ENTRY(c_to_double) = to_double;
FX_INTERFACE_ENTRY(c_to_cstr) = to_cstr;
FX_TYPE_VTABLE_INTERFACE_END(fx_convertible, FX_TYPE_CONVERTIBLE)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_comparable, FX_TYPE_COMPARABLE)
FX_INTERFACE_ENTRY(c_compare) = compare;
FX_TYPE_VTABLE_INTERFACE_END(fx_comparable, FX_TYPE_COMPARABLE)
FX_TYPE_CONSTRUCTOR("create", fx_string_create, 0, FX_TYPE_VOID);
FX_TYPE_CONSTRUCTOR(
"create_from_cstr",
@@ -1731,12 +1824,17 @@ FX_TYPE_CLASS_BEGIN(fx_string)
fx_string_get_cstr,
0,
FX_TYPE_STRING);
FX_TYPE_PROPERTY("length", get_length, NULL);
FX_TYPE_CLASS_END(fx_string)
FX_TYPE_DEFINITION_BEGIN(fx_string)
FX_TYPE_ID(0x200194f6, 0x0327, 0x4a82, 0xb9c9, 0xb62ddd038c33);
FX_TYPE_NAME("fx.string");
FX_TYPE_IMPLEMENTS(FX_TYPE_ITERABLE);
FX_TYPE_IMPLEMENTS(FX_TYPE_OPERABLE);
FX_TYPE_IMPLEMENTS(FX_TYPE_CONVERTIBLE);
FX_TYPE_IMPLEMENTS(FX_TYPE_COMPARABLE);
FX_TYPE_CLASS(fx_string_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_string_p);
FX_TYPE_INSTANCE_INIT(string_init);
@@ -1753,7 +1851,6 @@ FX_TYPE_CLASS_BEGIN(fx_string_iterator)
FX_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
FX_INTERFACE_ENTRY(it_erase) = NULL;
FX_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
FX_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
FX_TYPE_VTABLE_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR)
FX_TYPE_CLASS_END(fx_string_iterator)