Add D-style properties to the numeric types

- This is stuff like min and max for integral types and infinity and nan
  for floating point types.
This commit is contained in:
Randy Heit 2013-10-29 21:53:58 -05:00
parent fe21ceec56
commit e7616ec0bd
3 changed files with 162 additions and 3 deletions

View File

@ -34,6 +34,9 @@
// HEADER FILES ------------------------------------------------------------ // HEADER FILES ------------------------------------------------------------
#include <float.h>
#include <limits>
#include "dobject.h" #include "dobject.h"
#include "i_system.h" #include "i_system.h"
#include "actor.h" #include "actor.h"
@ -609,8 +612,10 @@ IMPLEMENT_CLASS(PInt)
//========================================================================== //==========================================================================
PInt::PInt() PInt::PInt()
: PBasicType(4, 4) : PBasicType(4, 4), Unsigned(false)
{ {
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, -0x7FFFFFFF - 1));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, 0x7FFFFFFF));
} }
//========================================================================== //==========================================================================
@ -622,6 +627,18 @@ PInt::PInt()
PInt::PInt(unsigned int size, bool unsign) PInt::PInt(unsigned int size, bool unsign)
: PBasicType(size, size), Unsigned(unsign) : PBasicType(size, size), Unsigned(unsign)
{ {
if (!unsign)
{
int maxval = (1 << ((8 * size) - 1)) - 1;
int minval = -maxval - 1;
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, minval));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, maxval));
}
else
{
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, 0u));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, (1u << (8 * size)) - 1));
}
} }
//========================================================================== //==========================================================================
@ -756,6 +773,21 @@ int PInt::GetRegType() const
IMPLEMENT_CLASS(PBool) IMPLEMENT_CLASS(PBool)
//==========================================================================
//
// PBool Default Constructor
//
//==========================================================================
PBool::PBool()
: PInt(sizeof(bool), true)
{
// Override the default max set by PInt's constructor
PSymbolConstNumeric *maxsym = static_cast<PSymbolConstNumeric *>(Symbols.FindSymbol(NAME_Max, false));
assert(maxsym != NULL && maxsym->IsKindOf(RUNTIME_CLASS(PSymbolConstNumeric)));
maxsym->Value = 1;
}
/* PFloat *****************************************************************/ /* PFloat *****************************************************************/
IMPLEMENT_CLASS(PFloat) IMPLEMENT_CLASS(PFloat)
@ -767,8 +799,9 @@ IMPLEMENT_CLASS(PFloat)
//========================================================================== //==========================================================================
PFloat::PFloat() PFloat::PFloat()
: PBasicType(4, 4) : PBasicType(8, 8)
{ {
SetDoubleSymbols();
} }
//========================================================================== //==========================================================================
@ -780,6 +813,101 @@ PFloat::PFloat()
PFloat::PFloat(unsigned int size) PFloat::PFloat(unsigned int size)
: PBasicType(size, size) : PBasicType(size, size)
{ {
if (size == 8)
{
SetDoubleSymbols();
}
else
{
assert(size == 4);
SetSingleSymbols();
}
}
//==========================================================================
//
// PFloat :: SetDoubleSymbols
//
// Setup constant values for 64-bit floats.
//
//==========================================================================
void PFloat::SetDoubleSymbols()
{
static const SymbolInitF symf[] =
{
{ NAME_Min_Normal, DBL_MIN },
{ NAME_Max, DBL_MAX },
{ NAME_Epsilon, DBL_EPSILON },
{ NAME_NaN, std::numeric_limits<double>::quiet_NaN() },
{ NAME_Infinity, std::numeric_limits<double>::infinity() },
{ NAME_Min_Denormal, std::numeric_limits<double>::denorm_min() }
};
static const SymbolInitI symi[] =
{
{ NAME_Dig, DBL_DIG },
{ NAME_Min_Exp, DBL_MIN_EXP },
{ NAME_Max_Exp, DBL_MAX_EXP },
{ NAME_Mant_Dig, DBL_MANT_DIG },
{ NAME_Min_10_Exp, DBL_MIN_10_EXP },
{ NAME_Max_10_Exp, DBL_MAX_10_EXP }
};
SetSymbols(symf, countof(symf));
SetSymbols(symi, countof(symi));
}
//==========================================================================
//
// PFloat :: SetSingleSymbols
//
// Setup constant values for 32-bit floats.
//
//==========================================================================
void PFloat::SetSingleSymbols()
{
static const SymbolInitF symf[] =
{
{ NAME_Min_Normal, FLT_MIN },
{ NAME_Max, FLT_MAX },
{ NAME_Epsilon, FLT_EPSILON },
{ NAME_NaN, std::numeric_limits<float>::quiet_NaN() },
{ NAME_Infinity, std::numeric_limits<float>::infinity() },
{ NAME_Min_Denormal, std::numeric_limits<float>::denorm_min() }
};
static const SymbolInitI symi[] =
{
{ NAME_Dig, FLT_DIG },
{ NAME_Min_Exp, FLT_MIN_EXP },
{ NAME_Max_Exp, FLT_MAX_EXP },
{ NAME_Mant_Dig, FLT_MANT_DIG },
{ NAME_Min_10_Exp, FLT_MIN_10_EXP },
{ NAME_Max_10_Exp, FLT_MAX_10_EXP }
};
SetSymbols(symf, countof(symf));
SetSymbols(symi, countof(symi));
}
//==========================================================================
//
// PFloat :: SetSymbols
//
//==========================================================================
void PFloat::SetSymbols(const PFloat::SymbolInitF *sym, size_t count)
{
for (size_t i = 0; i < count; ++i)
{
Symbols.AddSymbol(new PSymbolConstNumeric(sym[i].Name, this, sym[i].Value));
}
}
void PFloat::SetSymbols(const PFloat::SymbolInitI *sym, size_t count)
{
for (size_t i = 0; i < count; ++i)
{
Symbols.AddSymbol(new PSymbolConstNumeric(sym[i].Name, this, sym[i].Value));
}
} }
//========================================================================== //==========================================================================

View File

@ -315,7 +315,7 @@ class PBool : public PInt
{ {
DECLARE_CLASS(PBool, PInt); DECLARE_CLASS(PBool, PInt);
public: public:
PBool() : PInt(sizeof(bool), true) {} PBool();
}; };
class PFloat : public PBasicType class PFloat : public PBasicType
@ -331,6 +331,22 @@ public:
virtual int GetRegType() const; virtual int GetRegType() const;
protected: protected:
PFloat(); PFloat();
private:
struct SymbolInitF
{
ENamedName Name;
double Value;
};
struct SymbolInitI
{
ENamedName Name;
int Value;
};
void SetSingleSymbols();
void SetDoubleSymbols();
void SetSymbols(const SymbolInitF *syminit, size_t count);
void SetSymbols(const SymbolInitI *syminit, size_t count);
}; };
class PString : public PBasicType class PString : public PBasicType
@ -767,6 +783,7 @@ public:
PSymbolConstNumeric(FName name, PType *type=NULL) : PSymbolConst(name, type) {} PSymbolConstNumeric(FName name, PType *type=NULL) : PSymbolConst(name, type) {}
PSymbolConstNumeric(FName name, PType *type, int val) : PSymbolConst(name, type), Value(val) {} PSymbolConstNumeric(FName name, PType *type, int val) : PSymbolConst(name, type), Value(val) {}
PSymbolConstNumeric(FName name, PType *type, unsigned int val) : PSymbolConst(name, type), Value((int)val) {}
PSymbolConstNumeric(FName name, PType *type, double val) : PSymbolConst(name, type), Float(val) {} PSymbolConstNumeric(FName name, PType *type, double val) : PSymbolConst(name, type), Float(val) {}
PSymbolConstNumeric() {} PSymbolConstNumeric() {}
}; };

View File

@ -598,3 +598,17 @@ xx(Array)
xx(Sound) xx(Sound)
xx(State) xx(State)
xx(Fixed) xx(Fixed)
xx(Min)
xx(Max)
xx(Min_Normal)
xx(Min_Denormal)
xx(Epsilon)
xx(NaN)
xx(Infinity)
xx(Dig)
xx(Min_Exp)
xx(Max_Exp)
xx(Mant_Dig)
xx(Min_10_Exp)
xx(Max_10_Exp)