diff --git a/uppsrc/Core/Core.h b/uppsrc/Core/Core.h index 230ef88..74f54a2 100644 --- a/uppsrc/Core/Core.h +++ b/uppsrc/Core/Core.h @@ -168,6 +168,7 @@ #include #include +#include // fix MSC8 beta problem.... #ifdef COMPILER_MSC diff --git a/uppsrc/Core/Defs.h b/uppsrc/Core/Defs.h index e41e407..8e2213a 100644 --- a/uppsrc/Core/Defs.h +++ b/uppsrc/Core/Defs.h @@ -247,6 +247,8 @@ typedef long long unsigned uint64; typedef uint64 qword; +typedef std::complex cdouble; + #ifdef COMPILER_MSC #define I64(c) ((int64)COMBINE(c, i64)) #else @@ -325,6 +327,40 @@ public: NoCopy() {} }; +const int INT_NULL = INT_MIN; +const int64 INT64_NULL = INT64_MIN; + +const double DOUBLE_NULL = -1.0E+308; +const double DOUBLE_NULL_LIM = -1.0E+307; + +class Nuller { +public: + operator int() const { return INT_NULL; } + operator int64() const { return INT64_NULL; } + operator double() const { return DOUBLE_NULL; } + operator bool() const { return false; } + operator cdouble() const { return cdouble(DOUBLE_NULL, DOUBLE_NULL); } + + Nuller() {} +}; + +#ifdef flagSO +static const Nuller Null; +#else +extern const Nuller Null; +#endif + +template void SetNull(T& x) { x = Null; } +template<> inline void SetNull(cdouble& x) { x = Null.operator cdouble(); } + +template bool IsNull(const T& x) { return x.IsNullInstance(); } + +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 double& r) { return r < DOUBLE_NULL_LIM; } +template<> inline bool IsNull(const bool& r ) { return false; } +template<> inline bool IsNull(const cdouble& r) { return r.real() < DOUBLE_NULL_LIM || r.imag() < DOUBLE_NULL_LIM; } + #if defined(flagMT) #if defined(PLATFORM_WIN32) && defined(COMPILER_GCC) #define flagUSEMALLOC //MINGW does not support diff --git a/uppsrc/Core/Stream.cpp b/uppsrc/Core/Stream.cpp index d2eddd0..95bb29d 100644 --- a/uppsrc/Core/Stream.cpp +++ b/uppsrc/Core/Stream.cpp @@ -670,6 +670,13 @@ Stream& Stream::operator%(uint64& d) return *this; } +Stream& Stream::operator%(cdouble& d) { + double r,i; + if(IsStoring()) { r = d.real(); i = d.imag(); } + (*this) % r % i; + if(IsLoading()) { d = cdouble(r,i); } + return *this; +} Stream& Stream::operator%(String& s) { if(IsError()) return *this; diff --git a/uppsrc/Core/Stream.h b/uppsrc/Core/Stream.h index 11b31d2..e1f41e9 100644 --- a/uppsrc/Core/Stream.h +++ b/uppsrc/Core/Stream.h @@ -204,6 +204,7 @@ public: Stream& operator%(double& d); Stream& operator%(int64& d); Stream& operator%(uint64& d); + Stream& operator%(cdouble& d); Stream& operator%(String& s); Stream& operator/(String& s); diff --git a/uppsrc/Core/String.h b/uppsrc/Core/String.h index ab03d05..c3edd90 100644 --- a/uppsrc/Core/String.h +++ b/uppsrc/Core/String.h @@ -390,8 +390,6 @@ public: inline bool IsEmpty(const String& s) { return s.IsEmpty(); } -template bool IsNull(const T& x) { return x.IsNullInstance(); } - String FormatPtr(const void *p); template @@ -781,6 +779,7 @@ template<> inline String AsString(const char& a) { return String(a, 1 template<> inline String AsString(const signed char& a) { return String(a, 1); } template<> inline String AsString(const unsigned char& a) { return String(a, 1); } template<> inline String AsString(const bool& a) { return a ? "true" : "false"; } +template<> inline String AsString(const cdouble& x) { return String().Cat() << "C(" << x.real() << "," << x.imag() << ")"; } unsigned ctoi(int c); diff --git a/uppsrc/Core/Topt.h b/uppsrc/Core/Topt.h index eda7cda..da3c17c 100644 --- a/uppsrc/Core/Topt.h +++ b/uppsrc/Core/Topt.h @@ -391,6 +391,7 @@ template<> inline unsigned GetHashValue(const wchar_t& a) { return (const template<> inline unsigned GetHashValue(const int64& a) { return CombineHash((unsigned)a, (unsigned)(a >> 32)); } template<> inline unsigned GetHashValue(const uint64& a) { return GetHashValue((int64)a); } +template<> inline unsigned GetHashValue(const cdouble& x) { return CombineHash(x.real(), x.imag()); } unsigned GetHashValue0(const double& a); diff --git a/uppsrc/Core/Uuid.h b/uppsrc/Core/Uuid.h index b61d7d4..1efb085 100644 --- a/uppsrc/Core/Uuid.h +++ b/uppsrc/Core/Uuid.h @@ -2,7 +2,7 @@ struct Uuid : AssignValueTypeNo > { dword a, b, c, d; void Serialize(Stream& s); - bool IsNull() const { return a == 0 && b == 0 && c == 0 && d == 0; } + bool IsNullInstance() const { return a == 0 && b == 0 && c == 0 && d == 0; } void SetNull() { a = b = c = d = 0; } operator Value() const { return RichValue(*this); } @@ -32,9 +32,6 @@ inline bool operator!=(const Uuid& u, const Uuid& w) { } template<> -inline bool IsNull(const Uuid& id) { return id.IsNull(); } - -template<> inline String AsString(const Uuid& id) { return Format(id); } ValueGen& UuidValueGen(); diff --git a/uppsrc/Core/Value.cpp b/uppsrc/Core/Value.cpp index 314d658..2226afb 100644 --- a/uppsrc/Core/Value.cpp +++ b/uppsrc/Core/Value.cpp @@ -58,6 +58,7 @@ Value::Value(double d) { ptr = new RichValueRep(d); } Value::Value(bool b) { ptr = new RichValueRep(b); } Value::Value(Date d) { ptr = new RichValueRep(d); } Value::Value(Time t) { ptr = new RichValueRep