fx: add a generic container for primitive values and objects

This commit is contained in:
2026-05-03 20:21:58 +01:00
parent 7d44a6ec98
commit dab3fec6b8
2 changed files with 348 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
#ifndef FX_VALUE_H_
#define FX_VALUE_H_
#include <fx/object.h>
#include <fx/type.h>
#include <stdint.h>
#define FX_VALUE_BOOL(v) \
((fx_value) { \
.v_type.t_primitive = FX_VALUE_TYPE_BOOL, \
.v_bool = (v), \
})
#define FX_VALUE_INT(v) \
((fx_value) { \
.v_type.t_primitive = FX_VALUE_TYPE_INT, \
.v_int = (v), \
})
#define FX_VALUE_UINT(v) \
((fx_value) { \
.v_type.t_primitive = FX_VALUE_TYPE_UINT, \
.v_uint = (v), \
})
#define FX_VALUE_DOUBLE(v) \
((fx_value) { \
.v_type.t_primitive = FX_VALUE_TYPE_DOUBLE, \
.v_double = (v), \
})
#define FX_VALUE_CSTR(v) \
((fx_value) { \
.v_type.t_primitive = FX_VALUE_TYPE_CSTR, \
.v_cstr = (v), \
})
#define FX_VALUE_POINTER(v) \
((fx_value) { \
.v_type.t_primitive = FX_VALUE_TYPE_POINTER, \
.v_pointer = (v), \
})
typedef enum fx_value_type {
FX_VALUE_TYPE_NONE = 0,
FX_VALUE_TYPE_BOOL,
FX_VALUE_TYPE_INT,
FX_VALUE_TYPE_UINT,
FX_VALUE_TYPE_DOUBLE,
FX_VALUE_TYPE_CSTR,
FX_VALUE_TYPE_POINTER,
/* any value greater than this represents an object fx_type */
__FX_VALUE_TYPE_OBJECT_BOUNDARY = 1024,
} fx_value_type;
typedef struct fx_value {
union {
fx_value_type t_primitive;
fx_type t_object;
} v_type;
union {
bool v_bool;
intptr_t v_int;
uintptr_t v_uint;
double v_double;
const char *v_cstr;
void *v_pointer;
fx_object *v_object;
};
} fx_value;
FX_API void fx_value_init(fx_value *v, fx_type type);
FX_API void fx_value_init_primitive(fx_value *v, fx_value_type type);
FX_API void fx_value_unset(fx_value *v);
FX_API void fx_value_set_bool(fx_value *v, bool b);
FX_API void fx_value_set_int(fx_value *v, intptr_t i);
FX_API void fx_value_set_uint(fx_value *v, uintptr_t u);
FX_API void fx_value_set_double(fx_value *v, double d);
FX_API void fx_value_set_static_cstr(fx_value *v, const char *cstr);
FX_API void fx_value_set_pointer(fx_value *v, void *p);
FX_API void fx_value_set_object(fx_value *v, fx_object *obj);
FX_API bool fx_value_is_bool(const fx_value *v);
FX_API bool fx_value_is_int(const fx_value *v);
FX_API bool fx_value_is_uint(const fx_value *v);
FX_API bool fx_value_is_double(const fx_value *v);
FX_API bool fx_value_is_string(const fx_value *v);
FX_API bool fx_value_is_pointer(const fx_value *v);
FX_API bool fx_value_is_object(const fx_value *v, fx_type type);
FX_API bool fx_value_get_bool(const fx_value *v);
FX_API intptr_t fx_value_get_int(const fx_value *v);
FX_API uintptr_t fx_value_get_uint(const fx_value *v);
FX_API double fx_value_get_double(const fx_value *v);
FX_API const char *fx_value_get_cstr(const fx_value *v);
FX_API void *fx_value_get_pointer(fx_value *v);
FX_API const void *fx_value_get_pointer_c(const fx_value *v);
FX_API fx_object *fx_value_get_object(fx_value *v);
FX_API const fx_object *fx_value_get_object_c(const fx_value *v);
#endif
+248
View File
@@ -0,0 +1,248 @@
#include <fx/bool.h>
#include <fx/double.h>
#include <fx/int.h>
#include <fx/string.h>
#include <fx/uint.h>
#include <fx/value.h>
void fx_value_init(fx_value *v, fx_type type)
{
}
void fx_value_init_primitive(fx_value *v, fx_value_type type)
{
}
void fx_value_unset(fx_value *v)
{
}
void fx_value_set_bool(fx_value *v, bool b)
{
}
void fx_value_set_int(fx_value *v, intptr_t i)
{
}
void fx_value_set_uint(fx_value *v, uintptr_t u)
{
}
void fx_value_set_double(fx_value *v, double d)
{
}
void fx_value_set_static_cstr(fx_value *v, const char *cstr)
{
}
void fx_value_set_pointer(fx_value *v, void *p)
{
}
void fx_value_set_object(fx_value *v, fx_object *obj)
{
}
bool fx_value_is_bool(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_BOOL) {
return true;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_BOOL)) {
return true;
}
}
return false;
}
bool fx_value_is_int(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_INT) {
return true;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_INT)) {
return true;
}
}
return false;
}
bool fx_value_is_uint(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_UINT) {
return true;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_UINT)) {
return true;
}
}
return false;
}
bool fx_value_is_double(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_DOUBLE) {
return true;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_DOUBLE)) {
return true;
}
}
return false;
}
bool fx_value_is_string(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_CSTR) {
return true;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_STRING)) {
return true;
}
}
return false;
}
bool fx_value_is_pointer(const fx_value *v)
{
return (v->v_type.t_primitive == FX_VALUE_TYPE_POINTER);
}
bool fx_value_is_object(const fx_value *v, fx_type type)
{
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, type)) {
return true;
}
}
return false;
}
bool fx_value_get_bool(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_BOOL) {
return v->v_bool;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_BOOL)) {
return fx_bool_get_value(v->v_object);
}
}
return false;
}
intptr_t fx_value_get_int(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_INT) {
return v->v_int;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_INT)) {
return fx_int_get_value(v->v_object);
}
}
return 0;
}
uintptr_t fx_value_get_uint(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_UINT) {
return v->v_uint;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_UINT)) {
return fx_uint_get_value(v->v_object);
}
}
return 0;
}
double fx_value_get_double(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_DOUBLE) {
return v->v_uint;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_DOUBLE)) {
return fx_double_get_value(v->v_object);
}
}
return 0;
}
const char *fx_value_get_cstr(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_CSTR) {
return v->v_cstr;
}
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_STRING)) {
return fx_string_get_cstr(v->v_object);
}
}
return NULL;
}
void *fx_value_get_pointer(fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_POINTER) {
return v->v_pointer;
}
return NULL;
}
const void *fx_value_get_pointer_c(const fx_value *v)
{
if (v->v_type.t_primitive == FX_VALUE_TYPE_POINTER) {
return v->v_pointer;
}
return NULL;
}
fx_object *fx_value_get_object(fx_value *v)
{
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
return v->v_object;
}
return NULL;
}
const fx_object *fx_value_get_object_c(const fx_value *v)
{
if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) {
return v->v_object;
}
return NULL;
}