273 lines
5.6 KiB
C
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)
|