Core: Value float support

This commit is contained in:
Mirek Fidler 2023-10-29 20:58:52 +01:00
parent 42a65fc354
commit 5cb246126f
19 changed files with 371 additions and 55 deletions

122
autotest/Float/Etalon.log Normal file
View file

@ -0,0 +1,122 @@
* C:\upp\out\autotest\CLANGx64.Debug.Debug_Full\Float.exe 29.10.2023 20:57:55, user: cxl
===========
x = 0
IsNull(x) = false
v = 0
IsNumber(v) = true
(int)v = 0
(int64)v = 0
(bool)v = false
(double)v = 0
v == x = true
v == 1 = false
v > Value(1) = false
AsJSON(v) = 0
StoreAsJson(t) = {"x":0}
StoreAsXML(t) = <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE app>
<app>
<x value="0"/>
</app>
(float)ScanDouble(AsString(x)) = 0
===========
x = 0.23
IsNull(x) = false
v = 0.23
IsNumber(v) = true
(int)v = 0
(int64)v = 0
(bool)v = true
(double)v = 0.230000004172325
v == x = true
v == 1 = false
v > Value(1) = false
AsJSON(v) = 0.23
StoreAsJson(t) = {"x":0.23}
StoreAsXML(t) = <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE app>
<app>
<x value="0.23"/>
</app>
(float)ScanDouble(AsString(x)) = 0.23
===========
x = 1
IsNull(x) = false
v = 1
IsNumber(v) = true
(int)v = 1
(int64)v = 1
(bool)v = true
(double)v = 1
v == x = true
v == 1 = true
v > Value(1) = false
AsJSON(v) = 1
StoreAsJson(t) = {"x":1}
StoreAsXML(t) = <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE app>
<app>
<x value="1"/>
</app>
(float)ScanDouble(AsString(x)) = 1
===========
x = 1.23
IsNull(x) = false
v = 1.23
IsNumber(v) = true
(int)v = 1
(int64)v = 1
(bool)v = true
(double)v = 1.23000001907349
v == x = true
v == 1 = false
v > Value(1) = true
AsJSON(v) = 1.23
StoreAsJson(t) = {"x":1.23}
StoreAsXML(t) = <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE app>
<app>
<x value="1.23"/>
</app>
(float)ScanDouble(AsString(x)) = 1.23
===========
x = 51.23
IsNull(x) = false
v = 51.23
IsNumber(v) = true
(int)v = 51
(int64)v = 51
(bool)v = true
(double)v = 51.2299995422363
v == x = true
v == 1 = false
v > Value(1) = true
AsJSON(v) = 51.23
StoreAsJson(t) = {"x":51.23}
StoreAsXML(t) = <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE app>
<app>
<x value="51.23"/>
</app>
(float)ScanDouble(AsString(x)) = 51.23
===========
x =
IsNull(x) = true
v =
IsNumber(v) = true
(int)v =
(int64)v =
(bool)v = false
(double)v =
v == x = true
v == 1 = false
v > Value(1) = false
AsJSON(v) = null
StoreAsJson(t) = {"x":null}
StoreAsXML(t) = <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE app>
<app>
<x value=""/>
</app>
(float)ScanDouble(AsString(x)) =

10
autotest/Float/Float.upp Normal file
View file

@ -0,0 +1,10 @@
uses
Core;
file
Etalon.log,
main.cpp;
mainconfig
"" = "";

56
autotest/Float/main.cpp Normal file
View file

@ -0,0 +1,56 @@
#include <Core/Core.h>
using namespace Upp;
struct Foo {
float x;
void Jsonize(JsonIO& io) { io("x", x); }
void Xmlize(XmlIO& io) { io("x", x); }
};
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
auto Test = [&](float x) {
DLOG("===========");
DDUMP(x);
DDUMP(IsNull(x));
Value v = x;
DDUMP(v);
DDUMP(IsNumber(v));
DDUMP((int)v);
DDUMP((int64)v);
DDUMP((bool)v);
DDUMP((double)v);
DDUMP(v == x);
DDUMP(v == 1);
DDUMP(v > Value(1));
DDUMP(AsJSON(v));
Foo t, u, w;
t.x = x;
DDUMP(StoreAsJson(t));
LoadFromJson(u, StoreAsJson(t));
ASSERT(t.x == u.x);
DDUMP(StoreAsXML(t));
LoadFromXML(w, StoreAsXML(t));
ASSERT(t.x == w.x);
DDUMP((float)ScanDouble(AsString(x)));
ASSERT(x == (float)ScanDouble(AsString(x)));
ASSERT(v == (float)ScanDouble(AsString(x)));
};
Test(0);
Test(0.23);
Test(1);
Test(1.23);
Test(51.23);
Test(Null);
CheckLogEtalon();
}

View file

@ -409,6 +409,19 @@ String FormatDoubleN(double x)
return String(h, FormatDouble_(h, x, 15, FD_TOLERANCE(6)|FD_MINIMAL_EXP)); return String(h, FormatDouble_(h, x, 15, FD_TOLERANCE(6)|FD_MINIMAL_EXP));
} }
String FormatFloat(float x)
{
char h[512];
return String(h, FormatDouble_(h, x, 7, FD_TOLERANCE(6)|FD_MINIMAL_EXP|FD_SPECIAL));
}
String FormatFloatN(float x)
{
char h[512];
return String(h, FormatDouble_(h, x, 7, FD_TOLERANCE(6)|FD_MINIMAL_EXP));
}
char *FormatG(char *t, double x, int precision, dword flags) char *FormatG(char *t, double x, int precision, dword flags)
{ {
return FormatDouble_(t, x, precision, flags); return FormatDouble_(t, x, precision, flags);

View file

@ -265,12 +265,14 @@ const int INT_NULL = INT_MIN;
const int64 INT64_NULL = INT64_MIN; const int64 INT64_NULL = INT64_MIN;
constexpr double DOUBLE_NULL = -std::numeric_limits<double>::infinity(); constexpr double DOUBLE_NULL = -std::numeric_limits<double>::infinity();
constexpr float FLOAT_NULL = -std::numeric_limits<float>::infinity();
class Nuller { class Nuller {
public: public:
operator int() const { return INT_NULL; } operator int() const { return INT_NULL; }
operator int64() const { return INT64_NULL; } operator int64() const { return INT64_NULL; }
operator double() const { return DOUBLE_NULL; } operator double() const { return DOUBLE_NULL; }
operator float() const { return FLOAT_NULL; }
operator bool() const { return false; } operator bool() const { return false; }
Nuller() {} Nuller() {}
@ -285,6 +287,7 @@ template <class T> bool IsNull(const T& x) { return x.IsNullInstance(); }
template<> inline bool IsNull(const int& i) { return i == INT_NULL; } template<> inline bool IsNull(const int& i) { return i == INT_NULL; }
template<> inline bool IsNull(const int64& i) { return i == INT64_NULL; } template<> inline bool IsNull(const int64& i) { return i == INT64_NULL; }
template<> inline bool IsNull(const double& r) { return !(std::abs(r) < std::numeric_limits<double>::infinity()); } template<> inline bool IsNull(const double& r) { return !(std::abs(r) < std::numeric_limits<double>::infinity()); }
template<> inline bool IsNull(const float& r) { return !(std::abs(r) < std::numeric_limits<float>::infinity()); }
template<> inline bool IsNull(const bool& r ) { return false; } template<> inline bool IsNull(const bool& r ) { return false; }
#include "Heap.h" #include "Heap.h"

View file

@ -61,8 +61,8 @@ String FormatDouble(double x);
String FormatDoubleN(double x); String FormatDoubleN(double x);
inline String FormatFloat(float x) { return FormatDouble(x, 7, FD_TOLERANCE(6)|FD_MINIMAL_EXP|FD_SPECIAL); } String FormatFloat(float x);
inline String FormatFloatN(float x) { return FormatDouble(x, 7, FD_TOLERANCE(6)|FD_MINIMAL_EXP); } String FormatFloatN(float x);
String FormatDate(Date date, const char *format, int language = 0); String FormatDate(Date date, const char *format, int language = 0);
String FormatTime(Time time, const char *format, int language = 0); String FormatTime(Time time, const char *format, int language = 0);

View file

@ -143,9 +143,11 @@ String AsJSON(const Value& v, const String& sep, bool pretty)
if(IsNumber(v) && (IsNull(v) || IsNaN((double)v))) if(IsNumber(v) && (IsNull(v) || IsNaN((double)v)))
return "null"; return "null";
if(v.GetType() == INT_V) if(v.GetType() == INT_V)
return Format("%d", (int)v); return FormatInt((int)v);
if(v.GetType() == BOOL_V) if(v.GetType() == BOOL_V)
return (bool)v ? "true" : "false"; return (bool)v ? "true" : "false";
if(v.GetType() == FLOAT_V)
return FormatG((double)v, 7);
if(IsNumber(v)) if(IsNumber(v))
return FormatG((double)v, 15); return FormatG((double)v, 15);
if(IsString(v)) if(IsString(v))
@ -196,6 +198,31 @@ template<> void Jsonize(JsonIO& io, double& var)
io.Set(var); io.Set(var);
} }
template<> void Jsonize(JsonIO& io, float& var)
{
if(io.IsLoading()) {
const Value& v = io.Get();
if(IsNull(v)) {
var = Null;
return;
}
if(IsNumber(v)) {
var = io.Get();
return;
}
if(IsString(v)) {
double h = ScanDouble((String)v);
if(!IsNull(h)) {
var = (float)h;
return;
}
}
throw JsonizeError("number expected");
}
else
io.Set(var);
}
template<> void Jsonize(JsonIO& io, int& var) template<> void Jsonize(JsonIO& io, int& var)
{ {
double v = IntDbl(var); double v = IntDbl(var);

View file

@ -3,6 +3,7 @@ Value ParseJSON(const char *s);
inline String AsJSON(int i) { return IsNull(i) ? "null" : AsString(i); } inline String AsJSON(int i) { return IsNull(i) ? "null" : AsString(i); }
inline String AsJSON(double n) { return IsNull(n) ? "null" : AsString(n); } inline String AsJSON(double n) { return IsNull(n) ? "null" : AsString(n); }
inline String AsJSON(float f) { return IsNull(f) ? "null" : AsString(f); }
inline String AsJSON(bool b) { return b ? "true" : "false"; } inline String AsJSON(bool b) { return b ? "true" : "false"; }
inline String AsJSON(const String& s) { return AsCString(s, INT_MAX, NULL, ASCSTRING_JSON); } inline String AsJSON(const String& s) { return AsCString(s, INT_MAX, NULL, ASCSTRING_JSON); }
inline String AsJSON(const WString& s) { return AsCString(s.ToString(), INT_MAX, NULL, ASCSTRING_JSON); } inline String AsJSON(const WString& s) { return AsCString(s.ToString(), INT_MAX, NULL, ASCSTRING_JSON); }
@ -30,6 +31,7 @@ public:
Json& operator()(const char *key, const Value& value) { return CatRaw(key, AsJSON(value)); } Json& operator()(const char *key, const Value& value) { return CatRaw(key, AsJSON(value)); }
Json& operator()(const char *key, int i) { return CatRaw(key, AsJSON(i)); } Json& operator()(const char *key, int i) { return CatRaw(key, AsJSON(i)); }
Json& operator()(const char *key, double n) { return CatRaw(key, AsJSON(n)); } Json& operator()(const char *key, double n) { return CatRaw(key, AsJSON(n)); }
Json& operator()(const char *key, float f) { return CatRaw(key, AsJSON(f)); }
Json& operator()(const char *key, bool b) { return CatRaw(key, AsJSON(b)); } Json& operator()(const char *key, bool b) { return CatRaw(key, AsJSON(b)); }
Json& operator()(const char *key, Date d) { return CatRaw(key, AsJSON(d)); } Json& operator()(const char *key, Date d) { return CatRaw(key, AsJSON(d)); }
Json& operator()(const char *key, Time t) { return CatRaw(key, AsJSON(t)); } Json& operator()(const char *key, Time t) { return CatRaw(key, AsJSON(t)); }
@ -43,6 +45,7 @@ public:
Json(const char *key, const Value& value) { CatRaw(key, AsJSON(value)); } Json(const char *key, const Value& value) { CatRaw(key, AsJSON(value)); }
Json(const char *key, int i) { CatRaw(key, AsJSON(i)); } Json(const char *key, int i) { CatRaw(key, AsJSON(i)); }
Json(const char *key, double n) { CatRaw(key, AsJSON(n)); } Json(const char *key, double n) { CatRaw(key, AsJSON(n)); }
Json(const char *key, float f) { CatRaw(key, AsJSON(f)); }
Json(const char *key, bool b) { CatRaw(key, AsJSON(b)); } Json(const char *key, bool b) { CatRaw(key, AsJSON(b)); }
Json(const char *key, Date d) { CatRaw(key, AsJSON(d)); } Json(const char *key, Date d) { CatRaw(key, AsJSON(d)); }
Json(const char *key, Time t) { CatRaw(key, AsJSON(t)); } Json(const char *key, Time t) { CatRaw(key, AsJSON(t)); }
@ -68,6 +71,7 @@ public:
JsonArray& operator<<(const Value& value) { return CatRaw(AsJSON(value)); } JsonArray& operator<<(const Value& value) { return CatRaw(AsJSON(value)); }
JsonArray& operator<<(int i) { return CatRaw(AsJSON(i)); } JsonArray& operator<<(int i) { return CatRaw(AsJSON(i)); }
JsonArray& operator<<(double n) { return CatRaw(AsJSON(n)); } JsonArray& operator<<(double n) { return CatRaw(AsJSON(n)); }
JsonArray& operator<<(float f) { return CatRaw(AsJSON(f)); }
JsonArray& operator<<(bool b) { return CatRaw(AsJSON(b)); } JsonArray& operator<<(bool b) { return CatRaw(AsJSON(b)); }
JsonArray& operator<<(Date d) { return CatRaw(AsJSON(d)); } JsonArray& operator<<(Date d) { return CatRaw(AsJSON(d)); }
JsonArray& operator<<(Time t) { return CatRaw(AsJSON(t)); } JsonArray& operator<<(Time t) { return CatRaw(AsJSON(t)); }
@ -311,6 +315,7 @@ template<> void Jsonize(JsonIO& io, byte& var);
template<> void Jsonize(JsonIO& io, int16& var); template<> void Jsonize(JsonIO& io, int16& var);
template<> void Jsonize(JsonIO& io, int64& var); template<> void Jsonize(JsonIO& io, int64& var);
template<> void Jsonize(JsonIO& io, double& var); template<> void Jsonize(JsonIO& io, double& var);
template<> void Jsonize(JsonIO& io, float& var);
template<> void Jsonize(JsonIO& io, bool& var); template<> void Jsonize(JsonIO& io, bool& var);
template<> void Jsonize(JsonIO& io, String& var); template<> void Jsonize(JsonIO& io, String& var);
template<> void Jsonize(JsonIO& io, WString& var); template<> void Jsonize(JsonIO& io, WString& var);

View file

@ -194,6 +194,7 @@ int Value::GetOtherInt() const
if(IsNull()) return Null; if(IsNull()) return Null;
return data.IsSpecial(BOOL_V) ? (int)GetSmall<bool>() : return data.IsSpecial(BOOL_V) ? (int)GetSmall<bool>() :
data.IsSpecial(INT64_V) ? (int)GetSmall<int64>() : data.IsSpecial(INT64_V) ? (int)GetSmall<int64>() :
data.IsSpecial(FLOAT_V) ? (float)GetSmall<float>() :
(int)GetSmall<double>(); (int)GetSmall<double>();
} }
@ -202,6 +203,7 @@ int64 Value::GetOtherInt64() const
if(IsNull()) return Null; if(IsNull()) return Null;
return data.IsSpecial(BOOL_V) ? (int64)GetSmall<bool>() : return data.IsSpecial(BOOL_V) ? (int64)GetSmall<bool>() :
data.IsSpecial(INT_V) ? (int64)GetSmall<int>() : data.IsSpecial(INT_V) ? (int64)GetSmall<int>() :
data.IsSpecial(FLOAT_V) ? (float)GetSmall<float>() :
(int64)GetSmall<double>(); (int64)GetSmall<double>();
} }
@ -210,14 +212,25 @@ double Value::GetOtherDouble() const
if(IsNull()) return Null; if(IsNull()) return Null;
return data.IsSpecial(BOOL_V) ? (double)GetSmall<bool>() : return data.IsSpecial(BOOL_V) ? (double)GetSmall<bool>() :
data.IsSpecial(INT_V) ? (double)GetSmall<int>() : data.IsSpecial(INT_V) ? (double)GetSmall<int>() :
data.IsSpecial(FLOAT_V) ? (float)GetSmall<float>() :
(double)GetSmall<int64>(); (double)GetSmall<int64>();
} }
float Value::GetOtherFloat() const
{
if(IsNull()) return Null;
return data.IsSpecial(BOOL_V) ? (float)GetSmall<bool>() :
data.IsSpecial(INT_V) ? (float)GetSmall<int>() :
data.IsSpecial(DOUBLE_V) ? (float)GetSmall<double>() :
(float)GetSmall<int64>();
}
bool Value::GetOtherBool() const bool Value::GetOtherBool() const
{ {
if(IsNull()) return Null; if(IsNull()) return Null;
return data.IsSpecial(DOUBLE_V) ? (bool)GetSmall<double>() : return data.IsSpecial(DOUBLE_V) ? (bool)GetSmall<double>() :
data.IsSpecial(INT_V) ? (bool)GetSmall<int>() : data.IsSpecial(INT_V) ? (bool)GetSmall<int>() :
data.IsSpecial(FLOAT_V) ? (float)GetSmall<float>() :
(bool)GetSmall<int64>(); (bool)GetSmall<int64>();
} }
@ -264,6 +277,7 @@ String Value::GetName(dword type)
SVO_FN(s_String, String); SVO_FN(s_String, String);
SVO_FN(s_int, int); SVO_FN(s_int, int);
SVO_FN(s_double, double); SVO_FN(s_double, double);
SVO_FN(s_float, float);
SVO_FN(s_int64, int64); SVO_FN(s_int64, int64);
SVO_FN(s_bool, bool); SVO_FN(s_bool, bool);
SVO_FN(s_date, Date); SVO_FN(s_date, Date);
@ -307,6 +321,7 @@ Value::Sval *Value::svo[256] = {
&s_bool, //BOOL_V = 11; &s_bool, //BOOL_V = 11;
NULL, //VALUEMAP_V = 12; NULL, //VALUEMAP_V = 12;
&s_float, //FLOAT_V = 13;
}; };
Value::Void *ValueArrayDataCreate() Value::Void *ValueArrayDataCreate()
@ -329,6 +344,7 @@ void Value::RegisterStd()
Value::AddName(STRING_V, "String"); Value::AddName(STRING_V, "String");
Value::AddName(INT_V, "int"); Value::AddName(INT_V, "int");
Value::AddName(DOUBLE_V, "double"); Value::AddName(DOUBLE_V, "double");
Value::AddName(FLOAT_V, "float");
Value::AddName(VOID_V, "void"); Value::AddName(VOID_V, "void");
Value::AddName(DATE_V, "Date"); Value::AddName(DATE_V, "Date");
Value::AddName(TIME_V, "Time"); Value::AddName(TIME_V, "Time");
@ -719,6 +735,7 @@ String Value::GetName() const
static Tuple<byte, const char *> tp[] = { static Tuple<byte, const char *> tp[] = {
{ (byte)INT_V, "int" }, { (byte)INT_V, "int" },
{ (byte)DOUBLE_V, "double" }, { (byte)DOUBLE_V, "double" },
{ (byte)FLOAT_V, "float" },
{ (byte)VOIDV, "void" }, { (byte)VOIDV, "void" },
{ (byte)DATE_V, "Date" }, { (byte)DATE_V, "Date" },
{ (byte)TIME_V, "Time" }, { (byte)TIME_V, "Time" },

View file

@ -34,6 +34,7 @@ const dword INT64_V = 10;
const dword BOOL_V = 11; const dword BOOL_V = 11;
const dword VALUEMAP_V = 12; const dword VALUEMAP_V = 12;
const dword FLOAT_V = 13;
const dword UNKNOWN_V = (dword)0xffffffff; const dword UNKNOWN_V = (dword)0xffffffff;
@ -43,6 +44,7 @@ inline dword ValueTypeNo(const T *) { return StaticTypeNo<T>() +
template<> inline dword ValueTypeNo(const int*) { return INT_V; } template<> inline dword ValueTypeNo(const int*) { return INT_V; }
template<> inline dword ValueTypeNo(const int64*) { return INT64_V; } template<> inline dword ValueTypeNo(const int64*) { return INT64_V; }
template<> inline dword ValueTypeNo(const double*) { return DOUBLE_V; } template<> inline dword ValueTypeNo(const double*) { return DOUBLE_V; }
template<> inline dword ValueTypeNo(const float*) { return FLOAT_V; }
template<> inline dword ValueTypeNo(const bool*) { return BOOL_V; } template<> inline dword ValueTypeNo(const bool*) { return BOOL_V; }
template<> inline dword ValueTypeNo(const String*) { return STRING_V; } template<> inline dword ValueTypeNo(const String*) { return STRING_V; }
template<> inline dword ValueTypeNo(const WString*) { return WSTRING_V; } template<> inline dword ValueTypeNo(const WString*) { return WSTRING_V; }
@ -158,6 +160,7 @@ protected:
int GetOtherInt() const; int GetOtherInt() const;
int64 GetOtherInt64() const; int64 GetOtherInt64() const;
double GetOtherDouble() const; double GetOtherDouble() const;
float GetOtherFloat() const;
bool GetOtherBool() const; bool GetOtherBool() const;
Date GetOtherDate() const; Date GetOtherDate() const;
Time GetOtherTime() const; Time GetOtherTime() const;
@ -220,7 +223,7 @@ public:
operator Date() const { return Is(DATE_V) ? GetSmallRaw<Date>() : GetOtherDate(); } operator Date() const { return Is(DATE_V) ? GetSmallRaw<Date>() : GetOtherDate(); }
operator Time() const { return Is(TIME_V) ? GetSmallRaw<Time>() : GetOtherTime(); } operator Time() const { return Is(TIME_V) ? GetSmallRaw<Time>() : GetOtherTime(); }
operator double() const { return Is(DOUBLE_V) ? GetSmallRaw<double>() : GetOtherDouble(); } operator double() const { return Is(DOUBLE_V) ? GetSmallRaw<double>() : GetOtherDouble(); }
operator float() const { return float(Is(DOUBLE_V) ? GetSmallRaw<double>() : GetOtherDouble()); } operator float() const { return Is(FLOAT_V) ? GetSmallRaw<float>() : GetOtherFloat(); }
operator int() const { return Is(INT_V) ? GetSmallRaw<int>() : GetOtherInt(); } operator int() const { return Is(INT_V) ? GetSmallRaw<int>() : GetOtherInt(); }
operator int64() const { return Is(INT64_V) ? GetSmallRaw<int64>() : GetOtherInt64(); } operator int64() const { return Is(INT64_V) ? GetSmallRaw<int64>() : GetOtherInt64(); }
operator bool() const { return Is(BOOL_V) ? GetSmallRaw<bool>() : GetOtherBool(); } operator bool() const { return Is(BOOL_V) ? GetSmallRaw<bool>() : GetOtherBool(); }
@ -233,6 +236,7 @@ public:
Value(int i) : data(i, INT_V, String::SPECIAL) { Magic(); } Value(int i) : data(i, INT_V, String::SPECIAL) { Magic(); }
Value(int64 i) : data(i, INT64_V, String::SPECIAL) { Magic(); } Value(int64 i) : data(i, INT64_V, String::SPECIAL) { Magic(); }
Value(double d) : data(d, DOUBLE_V, String::SPECIAL) { Magic(); } Value(double d) : data(d, DOUBLE_V, String::SPECIAL) { Magic(); }
Value(float d) : data(d, FLOAT_V, String::SPECIAL) { Magic(); }
Value(bool b) : data(b, BOOL_V, String::SPECIAL) { Magic(); } Value(bool b) : data(b, BOOL_V, String::SPECIAL) { Magic(); }
Value(Date d) : data(d, DATE_V, String::SPECIAL) { Magic(); } Value(Date d) : data(d, DATE_V, String::SPECIAL) { Magic(); }
Value(Time t) : data(t, TIME_V, String::SPECIAL) { Magic(); } Value(Time t) : data(t, TIME_V, String::SPECIAL) { Magic(); }
@ -346,6 +350,7 @@ inline bool operator!=(T x, const Value& v) { return v.Is<VT>() ? (VT)v != x :
VALUE_COMPARE(int) VALUE_COMPARE(int)
VALUE_COMPARE(int64) VALUE_COMPARE(int64)
VALUE_COMPARE(double) VALUE_COMPARE(double)
VALUE_COMPARE(float)
VALUE_COMPARE(bool) VALUE_COMPARE(bool)
VALUE_COMPARE(Date) VALUE_COMPARE(Date)
VALUE_COMPARE(Time) VALUE_COMPARE(Time)
@ -367,7 +372,7 @@ inline bool IsDateTimeValueTypeNo(int q) { return (dword)q == DATE_V || (dword)q
inline bool IsVoid(const Value& v) { return v.IsVoid(); } inline bool IsVoid(const Value& v) { return v.IsVoid(); }
inline bool IsError(const Value& v) { return v.IsError(); } inline bool IsError(const Value& v) { return v.IsError(); }
inline bool IsString(const Value& v) { return v.Is<String>() || v.Is<WString>(); } inline bool IsString(const Value& v) { return v.Is<String>() || v.Is<WString>(); }
inline bool IsNumber(const Value& v) { return v.Is<double>() || v.Is<int>() || v.Is<int64>() || v.Is<bool>(); } inline bool IsNumber(const Value& v) { return v.Is<double>() || v.Is<float>() || v.Is<int>() || v.Is<int64>() || v.Is<bool>(); }
inline bool IsDateTime(const Value& v) { return v.Is<Date>() || v.Is<Time>(); } inline bool IsDateTime(const Value& v) { return v.Is<Date>() || v.Is<Time>(); }
inline bool IsValueArray(const Value& v) { return v.GetType() == VALUEARRAY_V || v.GetType() == VALUEMAP_V; } inline bool IsValueArray(const Value& v) { return v.GetType() == VALUEARRAY_V || v.GetType() == VALUEMAP_V; }
inline bool IsValueMap(const Value& v) { return IsValueArray(v); } inline bool IsValueMap(const Value& v) { return IsValueArray(v); }

View file

@ -12,6 +12,7 @@ Value::Value(const Value& v)
template<> template<>
inline bool IsPolyEqual(const bool& x, const Value& v) { inline bool IsPolyEqual(const bool& x, const Value& v) {
return v.Is<double>() && int(x) == double(v) return v.Is<double>() && int(x) == double(v)
|| v.Is<float>() && int(x) == float(v)
|| v.Is<int64>() && int(x) == int64(v) || v.Is<int64>() && int(x) == int64(v)
|| v.Is<int>() && int(x) == int(v); || v.Is<int>() && int(x) == int(v);
} }
@ -19,6 +20,7 @@ inline bool IsPolyEqual(const bool& x, const Value& v) {
template<> template<>
inline bool IsPolyEqual(const int& x, const Value& v) { inline bool IsPolyEqual(const int& x, const Value& v) {
return v.Is<double>() && x == double(v) return v.Is<double>() && x == double(v)
|| v.Is<float>() && x == float(v)
|| v.Is<int64>() && x == int64(v); || v.Is<int64>() && x == int64(v);
} }
@ -79,6 +81,11 @@ inline int PolyCompare(const double& x, const Value& v) {
return IsNumber(v) ? SgnCompare((double)x, (double)v) : 0; return IsNumber(v) ? SgnCompare((double)x, (double)v) : 0;
} }
template<>
inline int PolyCompare(const float& x, const Value& v) {
return IsNumber(v) ? SgnCompare((double)x, (double)v) : 0;
}
template<> template<>
inline int PolyCompare(const Date& x, const Value& v) { inline int PolyCompare(const Date& x, const Value& v) {
return v.Is<Time>() && SgnCompare(ToTime(x), Time(v)); return v.Is<Time>() && SgnCompare(ToTime(x), Time(v));
@ -106,6 +113,13 @@ inline hash_t ValueGetHashValue(const double& x) {
return UPP::GetHashValue(x); return UPP::GetHashValue(x);
} }
template<>
inline hash_t ValueGetHashValue(const float& x) {
if(x >= (float)INT64_MIN && x <= (float)INT64_MAX && (int64)x == x)
return UPP::GetHashValue((int64)x); // we want this to be equal to other number types
return UPP::GetHashValue(x);
}
template<> template<>
inline hash_t ValueGetHashValue(const Date& x) { inline hash_t ValueGetHashValue(const Date& x) {
return UPP::GetHashValue(ToTime(x)); return UPP::GetHashValue(ToTime(x));
@ -274,6 +288,8 @@ int Value::Compare(const Value& v) const
return SgnCompare(GetSmallRaw<int>(), v.GetSmallRaw<int>()); return SgnCompare(GetSmallRaw<int>(), v.GetSmallRaw<int>());
if(Is(DOUBLE_V) && v.Is(DOUBLE_V)) if(Is(DOUBLE_V) && v.Is(DOUBLE_V))
return SgnCompare(GetSmallRaw<double>(), v.GetSmallRaw<double>()); return SgnCompare(GetSmallRaw<double>(), v.GetSmallRaw<double>());
if(Is(FLOAT_V) && v.Is(FLOAT_V))
return SgnCompare(GetSmallRaw<float>(), v.GetSmallRaw<float>());
return Compare2(v); return Compare2(v);
} }

View file

@ -19,6 +19,7 @@ Ref::Ref(WString& s) { ptr = &s; m = &Single< StdRef<WString> >(); }
Ref::Ref(int& i) { ptr = &i; m = &Single< StdRef<int> >(); } Ref::Ref(int& i) { ptr = &i; m = &Single< StdRef<int> >(); }
Ref::Ref(int64& i) { ptr = &i; m = &Single< StdRef<int64> >(); } Ref::Ref(int64& i) { ptr = &i; m = &Single< StdRef<int64> >(); }
Ref::Ref(double& d) { ptr = &d; m = &Single< StdRef<double> >(); } Ref::Ref(double& d) { ptr = &d; m = &Single< StdRef<double> >(); }
Ref::Ref(float& f) { ptr = &f; m = &Single< StdRef<float> >(); }
Ref::Ref(bool& b) { ptr = &b; m = &Single< StdRef<bool> >(); } Ref::Ref(bool& b) { ptr = &b; m = &Single< StdRef<bool> >(); }
Ref::Ref(Date& d) { ptr = &d; m = &Single< StdRef<Date> >(); } Ref::Ref(Date& d) { ptr = &d; m = &Single< StdRef<Date> >(); }
Ref::Ref(Time& t) { ptr = &t; m = &Single< StdRef<Time> >(); } Ref::Ref(Time& t) { ptr = &t; m = &Single< StdRef<Time> >(); }
@ -653,4 +654,3 @@ INITBLOCK
} }
} }

View file

@ -4,12 +4,14 @@ inline const String& Nvl(const String& a, const String& b) { return IsNull(a
inline int Nvl(int a, int b) { return IsNull(a) ? b : a; } inline int Nvl(int a, int b) { return IsNull(a) ? b : a; }
inline int64 Nvl(int64 a, int64 b) { return IsNull(a) ? b : a; } inline int64 Nvl(int64 a, int64 b) { return IsNull(a) ? b : a; }
inline double Nvl(double a, double b) { return IsNull(a) ? b : a; } inline double Nvl(double a, double b) { return IsNull(a) ? b : a; }
inline float Nvl(float a, float b) { return IsNull(a) ? b : a; }
inline Date Nvl(Date a, Date b) { return IsNull(a) ? b : a; } inline Date Nvl(Date a, Date b) { return IsNull(a) ? b : a; }
inline Time Nvl(Time a, Time b) { return IsNull(a) ? b : a; } inline Time Nvl(Time a, Time b) { return IsNull(a) ? b : a; }
inline int Nvl(int a) { return Nvl(a, 0); } inline int Nvl(int a) { return Nvl(a, 0); }
inline int64 Nvl(int64 a) { return Nvl(a, (int64)0); } inline int64 Nvl(int64 a) { return Nvl(a, (int64)0); }
inline double Nvl(double a) { return Nvl(a, 0.0); } inline double Nvl(double a) { return Nvl(a, 0.0); }
inline float Nvl(float a) { return Nvl(a, 0.0f); }
template <class T> template <class T>
inline T Nvl(T a, T b, T c) { return Nvl(Nvl(a, b), c); } inline T Nvl(T a, T b, T c) { return Nvl(Nvl(a, b), c); }
@ -143,6 +145,7 @@ public:
Ref(int& i); Ref(int& i);
Ref(int64& i); Ref(int64& i);
Ref(double& d); Ref(double& d);
Ref(float& f);
Ref(bool& b); Ref(bool& b);
Ref(Date& d); Ref(Date& d);
Ref(Time& t); Ref(Time& t);
@ -163,6 +166,7 @@ inline WString& RefWString(Ref f) { return GetRef<WString>(f); }
inline int& RefInt(Ref f) { return GetRef<int>(f); } inline int& RefInt(Ref f) { return GetRef<int>(f); }
inline int64& RefInt64(Ref f) { return GetRef<int64>(f); } inline int64& RefInt64(Ref f) { return GetRef<int64>(f); }
inline double& RefDouble(Ref f) { return GetRef<double>(f); } inline double& RefDouble(Ref f) { return GetRef<double>(f); }
inline float& RefFloat(Ref f) { return GetRef<float>(f); }
inline bool& RefBool(Ref f) { return GetRef<bool>(f); } inline bool& RefBool(Ref f) { return GetRef<bool>(f); }
inline Date& RefDate(Ref f) { return GetRef<Date>(f); } inline Date& RefDate(Ref f) { return GetRef<Date>(f); }
inline Time& RefTime(Ref f) { return GetRef<Time>(f); } inline Time& RefTime(Ref f) { return GetRef<Time>(f); }

View file

@ -173,6 +173,11 @@ XmlTag& XmlTag::operator()(const char *attr, double q)
return operator()(attr, AsString(q)); return operator()(attr, AsString(q));
} }
XmlTag& XmlTag::operator()(const char *attr, float q)
{
return operator()(attr, AsString(q));
}
force_inline force_inline
String XmlParser::Convert(StringBuffer& b) String XmlParser::Convert(StringBuffer& b)
{ {
@ -681,6 +686,13 @@ double XmlParser::Double(const char *id, double def) const
return q < 0 ? def : ScanDouble(attr[q]); return q < 0 ? def : ScanDouble(attr[q]);
} }
float XmlParser::Float(const char *id, float def) const
{
if(id == attr1) return (float)ScanDouble(attrval1);
int q = attr.Find(id);
return q < 0 ? def : (float)ScanDouble(attr[q]);
}
bool XmlParser::IsText() bool XmlParser::IsText()
{ {
if(npreserve || preserveall) if(npreserve || preserveall)

View file

@ -29,6 +29,7 @@ public:
XmlTag& operator()(const char *attr, const char *val); XmlTag& operator()(const char *attr, const char *val);
XmlTag& operator()(const char *attr, int q); XmlTag& operator()(const char *attr, int q);
XmlTag& operator()(const char *attr, double q); XmlTag& operator()(const char *attr, double q);
XmlTag& operator()(const char *attr, float q);
XmlTag() {} XmlTag() {}
XmlTag(const char *tag) { Tag(tag); } XmlTag(const char *tag) { Tag(tag); }
@ -137,6 +138,7 @@ public:
String operator[](const char *id) const { return attr1 == id ? attrval1 : attr.Get(id, Null); } String operator[](const char *id) const { return attr1 == id ? attrval1 : attr.Get(id, Null); }
int Int(const char *id, int def = Null) const; int Int(const char *id, int def = Null) const;
double Double(const char *id, double def = Null) const; double Double(const char *id, double def = Null) const;
float Float(const char *id, float def = Null) const;
bool IsText(); bool IsText();
String PeekText() { return cdata; } String PeekText() { return cdata; }

View file

@ -62,7 +62,7 @@ template<> void XmlAttrLoad(dword& var, const String& text)
template<> String XmlAttrStore(const double& var) template<> String XmlAttrStore(const double& var)
{ {
return FormatG(var, 15); return AsString(var);
} }
template<> void XmlAttrLoad(double& var, const String& text) template<> void XmlAttrLoad(double& var, const String& text)
@ -70,6 +70,16 @@ template<> void XmlAttrLoad(double& var, const String& text)
var = ScanDouble(text); var = ScanDouble(text);
} }
template<> String XmlAttrStore(const float& var)
{
return AsString(var);
}
template<> void XmlAttrLoad(float& var, const String& text)
{
var = ScanDouble(text);
}
template<> String XmlAttrStore(const dword& var) template<> String XmlAttrStore(const dword& var)
{ {
return AsString(var); return AsString(var);
@ -147,6 +157,7 @@ template<> String XmlAttrStore(const Time& var) {
VALUE_XMLIZE(int); VALUE_XMLIZE(int);
VALUE_XMLIZE(dword); VALUE_XMLIZE(dword);
VALUE_XMLIZE(double); VALUE_XMLIZE(double);
VALUE_XMLIZE(float);
VALUE_XMLIZE(bool); VALUE_XMLIZE(bool);
VALUE_XMLIZE(int16); VALUE_XMLIZE(int16);
VALUE_XMLIZE(int64); VALUE_XMLIZE(int64);
@ -254,6 +265,11 @@ void StoreJsonValue(XmlIO& xio, const Value& v)
Xmlize(xio, b); Xmlize(xio, b);
} }
else else
if(v.GetType() == FLOAT_V) {
float f = v;
Xmlize(xio, f);
}
else
if(IsNumber(v)) { if(IsNumber(v)) {
double h = v; double h = v;
Xmlize(xio, h); Xmlize(xio, h);

View file

@ -81,6 +81,8 @@ template<> void XmlAttrLoad(dword& var, const String& text);
template<> String XmlAttrStore(const dword& var); template<> String XmlAttrStore(const dword& var);
template<> void XmlAttrLoad(double& var, const String& text); template<> void XmlAttrLoad(double& var, const String& text);
template<> String XmlAttrStore(const double& var); template<> String XmlAttrStore(const double& var);
template<> void XmlAttrLoad(float& var, const String& text);
template<> String XmlAttrStore(const float& var);
template<> void XmlAttrLoad(bool& var, const String& text); template<> void XmlAttrLoad(bool& var, const String& text);
template<> String XmlAttrStore(const bool& var); template<> String XmlAttrStore(const bool& var);
template <> void XmlAttrLoad(int16& var, const String& text); template <> void XmlAttrLoad(int16& var, const String& text);
@ -99,6 +101,7 @@ template<> void Xmlize(XmlIO& xml, WString& var);
template<> void Xmlize(XmlIO& xml, int& var); template<> void Xmlize(XmlIO& xml, int& var);
template<> void Xmlize(XmlIO& xml, dword& var); template<> void Xmlize(XmlIO& xml, dword& var);
template<> void Xmlize(XmlIO& xml, double& var); template<> void Xmlize(XmlIO& xml, double& var);
template<> void Xmlize(XmlIO& xml, float& var);
template<> void Xmlize(XmlIO& xml, bool& var); template<> void Xmlize(XmlIO& xml, bool& var);
template<> void Xmlize(XmlIO& xml, Date& var); template<> void Xmlize(XmlIO& xml, Date& var);
template<> void Xmlize(XmlIO& xml, Time& var); template<> void Xmlize(XmlIO& xml, Time& var);

View file

@ -182,6 +182,9 @@ sonIO][@(0.0.255) `&]_[*@3 io], [_^int16^ int16][@(0.0.255) `&]_[*@3 var])&]
sonIO][@(0.0.255) `&]_[*@3 io], [_^int64^ int64][@(0.0.255) `&]_[*@3 var])&] sonIO][@(0.0.255) `&]_[*@3 io], [_^int64^ int64][@(0.0.255) `&]_[*@3 var])&]
[s5;:Jsonize`(JsonIO`&`,double`&`): [@(0.0.255) template]_<>_[@(0.0.255) void]_[* Jsonize]( [s5;:Jsonize`(JsonIO`&`,double`&`): [@(0.0.255) template]_<>_[@(0.0.255) void]_[* Jsonize](
[_^JsonIO^ JsonIO][@(0.0.255) `&]_[*@3 io], [@(0.0.255) double`&]_[*@3 var])&] [_^JsonIO^ JsonIO][@(0.0.255) `&]_[*@3 io], [@(0.0.255) double`&]_[*@3 var])&]
[s5;:Upp`:`:Jsonize`(Upp`:`:JsonIO`&`,float`&`): [@(0.0.255) template]<>
[@(0.0.255) void] [* Jsonize](JsonIO[@(0.0.255) `&] io, [@(0.0.255) float`&]
var)&]
[s5;:Jsonize`(JsonIO`&`,bool`&`): [@(0.0.255) template]_<>_[@(0.0.255) void]_[* Jsonize]([_^JsonIO^ J [s5;:Jsonize`(JsonIO`&`,bool`&`): [@(0.0.255) template]_<>_[@(0.0.255) void]_[* Jsonize]([_^JsonIO^ J
sonIO][@(0.0.255) `&]_[*@3 io], [@(0.0.255) bool`&]_[*@3 var])&] sonIO][@(0.0.255) `&]_[*@3 io], [@(0.0.255) bool`&]_[*@3 var])&]
[s5;:Jsonize`(JsonIO`&`,String`&`): [@(0.0.255) template]_<>_[@(0.0.255) void]_[* Jsonize]( [s5;:Jsonize`(JsonIO`&`,String`&`): [@(0.0.255) template]_<>_[@(0.0.255) void]_[* Jsonize](
@ -208,8 +211,7 @@ data type.&]
which leads to somewhat unnatural results when key [%-*@4 K] is which leads to somewhat unnatural results when key [%-*@4 K] is
String or WString. [%-* StringMap ]alternative variant encodes String or WString. [%-* StringMap ]alternative variant encodes
map as JSON object with keys equal to map keys.&] map as JSON object with keys equal to map keys.&]
[s3;%% &] [s3; &]
[s3;%% &]
[s4;%% &] [s4;%% &]
[s5;:JsonizeBySerialize`(JsonIO`&`,T`&`): [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T]> [s5;:JsonizeBySerialize`(JsonIO`&`,T`&`): [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T]>
_[@(0.0.255) void]_[* JsonizeBySerialize]([_^JsonIO^ JsonIO][@(0.0.255) `&]_[*@3 jio], _[@(0.0.255) void]_[* JsonizeBySerialize]([_^JsonIO^ JsonIO][@(0.0.255) `&]_[*@3 jio],

View file

@ -70,6 +70,9 @@ har]_`*[*@3 val])&]
ator()]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 attr], [@(0.0.255) int]_[*@3 q])&] ator()]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 attr], [@(0.0.255) int]_[*@3 q])&]
[s5;:XmlTag`:`:operator`(`)`(const char`*`,double`): [_^XmlTag^ XmlTag][@(0.0.255) `&]_[* o [s5;:XmlTag`:`:operator`(`)`(const char`*`,double`): [_^XmlTag^ XmlTag][@(0.0.255) `&]_[* o
perator()]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 attr], [@(0.0.255) double]_[*@3 q])&] perator()]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 attr], [@(0.0.255) double]_[*@3 q])&]
[s5;:Upp`:`:XmlTag`:`:operator`(`)`(const char`*`,float`): XmlTag[@(0.0.255) `&]
operator()([@(0.0.255) const] [@(0.0.255) char] [@(0.0.255) `*]attr,
[@(0.0.255) float] q)&]
[s2;%% These methods add XML tag attributes.&] [s2;%% These methods add XML tag attributes.&]
[s3;%% &] [s3;%% &]
[s0;%% &] [s0;%% &]