Files
fx/fx/int.c
T

273 lines
5.6 KiB
C

#include <fx/int.h>
#include <fx/stream.h>
#include <inttypes.h>
#include <stdint.h>
/*** PRIVATE DATA *************************************************************/
enum int_type {
INT_REGULAR = 0,
INT_INF_POSITIVE,
INT_INF_NEGATIVE,
INT_NAN_POSITIVE,
INT_NAN_NEGATIVE,
};
struct fx_int_p {
enum int_type i_type;
intptr_t i_value;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static bool int_get_value(const struct fx_int_p *i)
{
return i->i_value;
}
static void int_set_value(struct fx_int_p *i, intptr_t v)
{
i->i_type = INT_REGULAR;
i->i_value = v;
}
static void int_set_value_nan(struct fx_int_p *i)
{
i->i_type = INT_NAN_POSITIVE;
i->i_value = 0;
}
static void int_set_value_nan_negative(struct fx_int_p *i)
{
i->i_type = INT_NAN_NEGATIVE;
i->i_value = 0;
}
static void int_set_value_inf(struct fx_int_p *i)
{
i->i_type = INT_INF_POSITIVE;
i->i_value = 0;
}
static void int_set_value_inf_negative(struct fx_int_p *i)
{
i->i_type = INT_INF_NEGATIVE;
i->i_value = 0;
}
static bool int_is_nan(struct fx_int_p *i)
{
return i->i_type == INT_NAN_POSITIVE || i->i_type == INT_NAN_NEGATIVE;
}
static bool int_is_nan_positive(struct fx_int_p *i)
{
return i->i_type == INT_NAN_POSITIVE;
}
static bool int_is_nan_negative(struct fx_int_p *i)
{
return i->i_type == INT_NAN_NEGATIVE;
}
static bool int_is_inf(struct fx_int_p *i)
{
return i->i_type == INT_INF_POSITIVE || i->i_type == INT_INF_NEGATIVE;
}
static bool int_is_inf_positive(struct fx_int_p *i)
{
return i->i_type == INT_INF_POSITIVE;
}
static bool int_is_inf_negative(struct fx_int_p *i)
{
return i->i_type == INT_INF_NEGATIVE;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_int *fx_int_create(intptr_t value)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_REGULAR;
p->i_value = value;
return i;
}
fx_int *fx_int_create_nan(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_NAN_POSITIVE;
p->i_value = 0;
return i;
}
fx_int *fx_int_create_nan_negative(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_NAN_NEGATIVE;
p->i_value = 0;
return i;
}
fx_int *fx_int_create_inf(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_INF_POSITIVE;
p->i_value = 0;
return i;
}
fx_int *fx_int_create_inf_negative(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_INF_NEGATIVE;
p->i_value = 0;
return i;
}
intptr_t fx_int_get_value(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_get_value, i);
}
void fx_int_set_value(fx_int *i, intptr_t v)
{
FX_CLASS_DISPATCH_STATIC_V(FX_TYPE_INT, int_set_value, i, v);
}
void fx_int_set_value_nan(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_nan, i);
}
void fx_int_set_value_nan_negative(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_nan_negative, i);
}
void fx_int_set_value_inf(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_inf, i);
}
void fx_int_set_value_inf_negative(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_inf_negative, i);
}
bool fx_int_is_nan(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_nan, i);
}
bool fx_int_is_nan_positive(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_nan_positive, i);
}
bool fx_int_is_nan_negative(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_nan_negative, i);
}
bool fx_int_is_inf(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_inf, i);
}
bool fx_int_is_inf_positive(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_inf_positive, i);
}
bool fx_int_is_inf_negative(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_inf_negative, i);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void int_init(fx_object *obj, void *priv)
{
struct fx_int_p *i = priv;
i->i_type = INT_REGULAR;
i->i_value = 0;
}
static void int_fini(fx_object *obj, void *priv)
{
}
static void int_to_string(const fx_object *obj, fx_stream *out)
{
struct fx_int_p *i = fx_object_get_private(obj, FX_TYPE_INT);
switch (i->i_type) {
case INT_REGULAR:
fx_stream_write_fmt(out, NULL, "%" PRIdPTR, i->i_value);
break;
case INT_INF_POSITIVE:
fx_stream_write_cstr(out, "inf", NULL);
break;
case INT_INF_NEGATIVE:
fx_stream_write_cstr(out, "-inf", NULL);
break;
case INT_NAN_POSITIVE:
fx_stream_write_cstr(out, "NaN", NULL);
break;
case INT_NAN_NEGATIVE:
fx_stream_write_cstr(out, "-NaN", NULL);
break;
default:
break;
}
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_int)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = int_to_string;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_int)
FX_TYPE_DEFINITION_BEGIN(fx_int)
FX_TYPE_ID(0x3b20f57a, 0x2ddf, 0x4682, 0x81c4, 0x4fe404a6524e);
FX_TYPE_CLASS(fx_int_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_int_p);
FX_TYPE_INSTANCE_INIT(int_init);
FX_TYPE_INSTANCE_FINI(int_fini);
FX_TYPE_DEFINITION_END(fx_int)