/source/Core/Scalar.cpp
https://gitlab.com/jorjpimm/lldb · C++ · 1410 lines · 1218 code · 113 blank · 79 comment · 128 complexity · 0b724427206f3abee648c44985986061 MD5 · raw file
- //===-- Scalar.cpp ----------------------------------------------*- C++ -*-===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "lldb/Core/Scalar.h"
- #include <math.h>
- #include <inttypes.h>
- #include "lldb/Interpreter/Args.h"
- #include "lldb/Core/Error.h"
- #include "lldb/Core/Stream.h"
- #include "lldb/Core/DataExtractor.h"
- #include "lldb/Host/Endian.h"
- #include "Plugins/Process/Utility/InstructionUtils.h"
- using namespace lldb;
- using namespace lldb_private;
- //----------------------------------------------------------------------
- // Promote to max type currently follows the ANSI C rule for type
- // promotion in expressions.
- //----------------------------------------------------------------------
- static Scalar::Type
- PromoteToMaxType
- (
- const Scalar& lhs, // The const left hand side object
- const Scalar& rhs, // The const right hand side object
- Scalar& temp_value, // A modifiable temp value than can be used to hold either the promoted lhs or rhs object
- const Scalar* &promoted_lhs_ptr, // Pointer to the resulting possibly promoted value of lhs (at most one of lhs/rhs will get promoted)
- const Scalar* &promoted_rhs_ptr // Pointer to the resulting possibly promoted value of rhs (at most one of lhs/rhs will get promoted)
- )
- {
- Scalar result;
- // Initialize the promoted values for both the right and left hand side values
- // to be the objects themselves. If no promotion is needed (both right and left
- // have the same type), then the temp_value will not get used.
- promoted_lhs_ptr = &lhs;
- promoted_rhs_ptr = &rhs;
- // Extract the types of both the right and left hand side values
- Scalar::Type lhs_type = lhs.GetType();
- Scalar::Type rhs_type = rhs.GetType();
- if (lhs_type > rhs_type)
- {
- // Right hand side need to be promoted
- temp_value = rhs; // Copy right hand side into the temp value
- if (temp_value.Promote(lhs_type)) // Promote it
- promoted_rhs_ptr = &temp_value; // Update the pointer for the promoted right hand side
- }
- else if (lhs_type < rhs_type)
- {
- // Left hand side need to be promoted
- temp_value = lhs; // Copy left hand side value into the temp value
- if (temp_value.Promote(rhs_type)) // Promote it
- promoted_lhs_ptr = &temp_value; // Update the pointer for the promoted left hand side
- }
- // Make sure our type promotion worked as expected
- if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
- return promoted_lhs_ptr->GetType(); // Return the resulting max type
- // Return the void type (zero) if we fail to promote either of the values.
- return Scalar::e_void;
- }
- //----------------------------------------------------------------------
- // Scalar constructor
- //----------------------------------------------------------------------
- Scalar::Scalar() :
- m_type(e_void),
- m_data()
- {
- }
- //----------------------------------------------------------------------
- // Scalar copy constructor
- //----------------------------------------------------------------------
- Scalar::Scalar(const Scalar& rhs) :
- m_type(rhs.m_type),
- m_data(rhs.m_data) // TODO: verify that for C++ this will correctly copy the union??
- {
- }
- //Scalar::Scalar(const RegisterValue& reg) :
- // m_type(e_void),
- // m_data()
- //{
- // switch (reg.info.encoding)
- // {
- // case eEncodingUint: // unsigned integer
- // switch (reg.info.byte_size)
- // {
- // case 1: m_type = e_uint; m_data.uint = reg.value.uint8; break;
- // case 2: m_type = e_uint; m_data.uint = reg.value.uint16; break;
- // case 4: m_type = e_uint; m_data.uint = reg.value.uint32; break;
- // case 8: m_type = e_ulonglong; m_data.ulonglong = reg.value.uint64; break;
- // break;
- // }
- // break;
- //
- // case eEncodingSint: // signed integer
- // switch (reg.info.byte_size)
- // {
- // case 1: m_type = e_sint; m_data.sint = reg.value.sint8; break;
- // case 2: m_type = e_sint; m_data.sint = reg.value.sint16; break;
- // case 4: m_type = e_sint; m_data.sint = reg.value.sint32; break;
- // case 8: m_type = e_slonglong; m_data.slonglong = reg.value.sint64; break;
- // break;
- // }
- // break;
- //
- // case eEncodingIEEE754: // float
- // switch (reg.info.byte_size)
- // {
- // case 4: m_type = e_float; m_data.flt = reg.value.float32; break;
- // case 8: m_type = e_double; m_data.dbl = reg.value.float64; break;
- // break;
- // }
- // break;
- // case eEncodingVector: // vector registers
- // break;
- // }
- //}
- bool
- Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
- {
- size_t byte_size = GetByteSize();
- if (byte_size > 0)
- {
- if (limit_byte_size < byte_size)
- {
- if (lldb::endian::InlHostByteOrder() == eByteOrderLittle)
- {
- // On little endian systems if we want fewer bytes from the
- // current type we just specify fewer bytes since the LSByte
- // is first...
- data.SetData((uint8_t*)&m_data, limit_byte_size, lldb::endian::InlHostByteOrder());
- }
- else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
- {
- // On big endian systems if we want fewer bytes from the
- // current type have to advance our initial byte pointer and
- // trim down the number of bytes since the MSByte is first
- data.SetData(((uint8_t*)&m_data) + byte_size - limit_byte_size, limit_byte_size, lldb::endian::InlHostByteOrder());
- }
- }
- else
- {
- // We want all of the data
- data.SetData((uint8_t*)&m_data, byte_size, lldb::endian::InlHostByteOrder());
- }
- return true;
- }
- data.Clear();
- return false;
- }
- size_t
- Scalar::GetByteSize() const
- {
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint: return sizeof(m_data.sint);
- case e_uint: return sizeof(m_data.uint);
- case e_slong: return sizeof(m_data.slong);
- case e_ulong: return sizeof(m_data.ulong);
- case e_slonglong: return sizeof(m_data.slonglong);
- case e_ulonglong: return sizeof(m_data.ulonglong);
- case e_float: return sizeof(m_data.flt);
- case e_double: return sizeof(m_data.dbl);
- case e_long_double: return sizeof(m_data.ldbl);
- }
- return 0;
- }
- bool
- Scalar::IsZero() const
- {
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint: return m_data.sint == 0;
- case e_uint: return m_data.uint == 0;
- case e_slong: return m_data.slong == 0;
- case e_ulong: return m_data.ulong == 0;
- case e_slonglong: return m_data.slonglong == 0;
- case e_ulonglong: return m_data.ulonglong == 0;
- case e_float: return m_data.flt == 0.0f;
- case e_double: return m_data.dbl == 0.0;
- case e_long_double: return m_data.ldbl == 0.0;
- }
- return false;
- }
- void
- Scalar::GetValue (Stream *s, bool show_type) const
- {
- if (show_type)
- s->Printf("(%s) ", GetTypeAsCString());
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint: s->Printf("%i", m_data.sint); break;
- case e_uint: s->Printf("0x%8.8x", m_data.uint); break;
- case e_slong: s->Printf("%li", m_data.slong); break;
- case e_ulong: s->Printf("0x%8.8lx", m_data.ulong); break;
- case e_slonglong: s->Printf("%lli", m_data.slonglong); break;
- case e_ulonglong: s->Printf("0x%16.16llx", m_data.ulonglong); break;
- case e_float: s->Printf("%f", m_data.flt); break;
- case e_double: s->Printf("%g", m_data.dbl); break;
- case e_long_double: s->Printf("%Lg", m_data.ldbl); break;
- }
- }
- const char *
- Scalar::GetTypeAsCString() const
- {
- switch (m_type)
- {
- case e_void: return "void";
- case e_sint: return "int";
- case e_uint: return "unsigned int";
- case e_slong: return "long";
- case e_ulong: return "unsigned long";
- case e_slonglong: return "long long";
- case e_ulonglong: return "unsigned long long";
- case e_float: return "float";
- case e_double: return "double";
- case e_long_double: return "long double";
- }
- return "<invalid Scalar type>";
- }
- //----------------------------------------------------------------------
- // Scalar copy constructor
- //----------------------------------------------------------------------
- Scalar&
- Scalar::operator=(const Scalar& rhs)
- {
- if (this != &rhs)
- {
- m_type = rhs.m_type;
- ::memcpy (&m_data, &rhs.m_data, sizeof(m_data));
- }
- return *this;
- }
- Scalar&
- Scalar::operator= (const int v)
- {
- m_type = e_sint;
- m_data.sint = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (unsigned int v)
- {
- m_type = e_uint;
- m_data.uint = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (long v)
- {
- m_type = e_slong;
- m_data.slong = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (unsigned long v)
- {
- m_type = e_ulong;
- m_data.ulong = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (long long v)
- {
- m_type = e_slonglong;
- m_data.slonglong = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (unsigned long long v)
- {
- m_type = e_ulonglong;
- m_data.ulonglong = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (float v)
- {
- m_type = e_float;
- m_data.flt = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (double v)
- {
- m_type = e_double;
- m_data.dbl = v;
- return *this;
- }
- Scalar&
- Scalar::operator= (long double v)
- {
- m_type = e_long_double;
- m_data.ldbl = v;
- return *this;
- }
- //----------------------------------------------------------------------
- // Destructor
- //----------------------------------------------------------------------
- Scalar::~Scalar()
- {
- }
- bool
- Scalar::Promote(Scalar::Type type)
- {
- bool success = false;
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint:
- switch (type)
- {
- case e_void: break;
- case e_sint: success = true; break;
- case e_uint: m_data.uint = m_data.sint; success = true; break;
- case e_slong: m_data.slong = m_data.sint; success = true; break;
- case e_ulong: m_data.ulong = m_data.sint; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.sint; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.sint; success = true; break;
- case e_float: m_data.flt = m_data.sint; success = true; break;
- case e_double: m_data.dbl = m_data.sint; success = true; break;
- case e_long_double: m_data.ldbl = m_data.sint; success = true; break;
- }
- break;
- case e_uint:
- switch (type)
- {
- case e_void:
- case e_sint: break;
- case e_uint: success = true; break;
- case e_slong: m_data.slong = m_data.uint; success = true; break;
- case e_ulong: m_data.ulong = m_data.uint; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.uint; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.uint; success = true; break;
- case e_float: m_data.flt = m_data.uint; success = true; break;
- case e_double: m_data.dbl = m_data.uint; success = true; break;
- case e_long_double: m_data.ldbl = m_data.uint; success = true; break;
- }
- break;
- case e_slong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint: break;
- case e_slong: success = true; break;
- case e_ulong: m_data.ulong = m_data.slong; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.slong; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.slong; success = true; break;
- case e_float: m_data.flt = m_data.slong; success = true; break;
- case e_double: m_data.dbl = m_data.slong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.slong; success = true; break;
- }
- break;
- case e_ulong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong: break;
- case e_ulong: success = true; break;
- case e_slonglong: m_data.slonglong = m_data.ulong; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.ulong; success = true; break;
- case e_float: m_data.flt = m_data.ulong; success = true; break;
- case e_double: m_data.dbl = m_data.ulong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.ulong; success = true; break;
- }
- break;
- case e_slonglong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong: break;
- case e_slonglong: success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.slonglong; success = true; break;
- case e_float: m_data.flt = m_data.slonglong; success = true; break;
- case e_double: m_data.dbl = m_data.slonglong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.slonglong; success = true; break;
- }
- break;
- case e_ulonglong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong: break;
- case e_ulonglong: success = true; break;
- case e_float: m_data.flt = m_data.ulonglong; success = true; break;
- case e_double: m_data.dbl = m_data.ulonglong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break;
- }
- break;
- case e_float:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong: break;
- case e_float: success = true; break;
- case e_double: m_data.dbl = m_data.flt; success = true; break;
- case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break;
- }
- break;
- case e_double:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_float: break;
- case e_double: success = true; break;
- case e_long_double: m_data.ldbl = m_data.dbl; success = true; break;
- }
- break;
- case e_long_double:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_float:
- case e_double: break;
- case e_long_double: success = true; break;
- }
- break;
- }
- if (success)
- m_type = type;
- return success;
- }
- const char *
- Scalar::GetValueTypeAsCString (Scalar::Type type)
- {
- switch (type)
- {
- case e_void: return "void";
- case e_sint: return "int";
- case e_uint: return "unsigned int";
- case e_slong: return "long";
- case e_ulong: return "unsigned long";
- case e_slonglong: return "long long";
- case e_ulonglong: return "unsigned long long";
- case e_float: return "float";
- case e_double: return "double";
- case e_long_double: return "long double";
- }
- return "???";
- }
- Scalar::Type
- Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
- {
- if (byte_size <= sizeof(sint_t))
- return e_sint;
- if (byte_size <= sizeof(slong_t))
- return e_slong;
- if (byte_size <= sizeof(slonglong_t))
- return e_slonglong;
- return e_void;
- }
- Scalar::Type
- Scalar::GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size)
- {
- if (byte_size <= sizeof(uint_t))
- return e_uint;
- if (byte_size <= sizeof(ulong_t))
- return e_ulong;
- if (byte_size <= sizeof(ulonglong_t))
- return e_ulonglong;
- return e_void;
- }
- Scalar::Type
- Scalar::GetValueTypeForFloatWithByteSize (size_t byte_size)
- {
- if (byte_size == sizeof(float_t))
- return e_float;
- if (byte_size == sizeof(double_t))
- return e_double;
- if (byte_size == sizeof(long_double_t))
- return e_long_double;
- return e_void;
- }
- bool
- Scalar::Cast(Scalar::Type type)
- {
- bool success = false;
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint:
- switch (type)
- {
- case e_void: break;
- case e_sint: success = true; break;
- case e_uint: m_data.uint = m_data.sint; success = true; break;
- case e_slong: m_data.slong = m_data.sint; success = true; break;
- case e_ulong: m_data.ulong = m_data.sint; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.sint; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.sint; success = true; break;
- case e_float: m_data.flt = m_data.sint; success = true; break;
- case e_double: m_data.dbl = m_data.sint; success = true; break;
- case e_long_double: m_data.ldbl = m_data.sint; success = true; break;
- }
- break;
- case e_uint:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = m_data.uint; success = true; break;
- case e_uint: success = true; break;
- case e_slong: m_data.slong = m_data.uint; success = true; break;
- case e_ulong: m_data.ulong = m_data.uint; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.uint; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.uint; success = true; break;
- case e_float: m_data.flt = m_data.uint; success = true; break;
- case e_double: m_data.dbl = m_data.uint; success = true; break;
- case e_long_double: m_data.ldbl = m_data.uint; success = true; break;
- }
- break;
- case e_slong:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.slong; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.slong; success = true; break;
- case e_slong: success = true; break;
- case e_ulong: m_data.ulong = m_data.slong; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.slong; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.slong; success = true; break;
- case e_float: m_data.flt = m_data.slong; success = true; break;
- case e_double: m_data.dbl = m_data.slong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.slong; success = true; break;
- }
- break;
- case e_ulong:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.ulong; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.ulong; success = true; break;
- case e_slong: m_data.slong = m_data.ulong; success = true; break;
- case e_ulong: success = true; break;
- case e_slonglong: m_data.slonglong = m_data.ulong; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.ulong; success = true; break;
- case e_float: m_data.flt = m_data.ulong; success = true; break;
- case e_double: m_data.dbl = m_data.ulong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.ulong; success = true; break;
- }
- break;
- case e_slonglong:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.slonglong; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.slonglong; success = true; break;
- case e_slong: m_data.slong = m_data.slonglong; success = true; break;
- case e_ulong: m_data.ulong = m_data.slonglong; success = true; break;
- case e_slonglong: success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.slonglong; success = true; break;
- case e_float: m_data.flt = m_data.slonglong; success = true; break;
- case e_double: m_data.dbl = m_data.slonglong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.slonglong; success = true; break;
- }
- break;
- case e_ulonglong:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.ulonglong; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.ulonglong; success = true; break;
- case e_slong: m_data.slong = m_data.ulonglong; success = true; break;
- case e_ulong: m_data.ulong = m_data.ulonglong; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.ulonglong; success = true; break;
- case e_ulonglong: success = true; break;
- case e_float: m_data.flt = m_data.ulonglong; success = true; break;
- case e_double: m_data.dbl = m_data.ulonglong; success = true; break;
- case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break;
- }
- break;
- case e_float:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.flt; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.flt; success = true; break;
- case e_slong: m_data.slong = (slong_t)m_data.flt; success = true; break;
- case e_ulong: m_data.ulong = (ulong_t)m_data.flt; success = true; break;
- case e_slonglong: m_data.slonglong = (slonglong_t)m_data.flt; success = true; break;
- case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.flt; success = true; break;
- case e_float: success = true; break;
- case e_double: m_data.dbl = m_data.flt; success = true; break;
- case e_long_double: m_data.ldbl = m_data.flt; success = true; break;
- }
- break;
- case e_double:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.dbl; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.dbl; success = true; break;
- case e_slong: m_data.slong = (slong_t)m_data.dbl; success = true; break;
- case e_ulong: m_data.ulong = (ulong_t)m_data.dbl; success = true; break;
- case e_slonglong: m_data.slonglong = (slonglong_t)m_data.dbl; success = true; break;
- case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.dbl; success = true; break;
- case e_float: m_data.flt = (float_t)m_data.dbl; success = true; break;
- case e_double: success = true; break;
- case e_long_double: m_data.ldbl = m_data.dbl; success = true; break;
- }
- break;
- case e_long_double:
- switch (type)
- {
- case e_void:
- case e_sint: m_data.sint = (sint_t)m_data.ldbl; success = true; break;
- case e_uint: m_data.uint = (uint_t)m_data.ldbl; success = true; break;
- case e_slong: m_data.slong = (slong_t)m_data.ldbl; success = true; break;
- case e_ulong: m_data.ulong = (ulong_t)m_data.ldbl; success = true; break;
- case e_slonglong: m_data.slonglong = (slonglong_t)m_data.ldbl; success = true; break;
- case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.ldbl; success = true; break;
- case e_float: m_data.flt = (float_t)m_data.ldbl; success = true; break;
- case e_double: m_data.dbl = (double_t)m_data.ldbl; success = true; break;
- case e_long_double: success = true; break;
- }
- break;
- }
- if (success)
- m_type = type;
- return success;
- }
- bool
- Scalar::MakeSigned ()
- {
- bool success = false;
-
- switch (m_type)
- {
- case e_void: break;
- case e_sint: success = true; break;
- case e_uint: m_type = e_sint; success = true; break;
- case e_slong: success = true; break;
- case e_ulong: m_type = e_slong; success = true; break;
- case e_slonglong: success = true; break;
- case e_ulonglong: m_type = e_slonglong; success = true; break;
- case e_float: success = true; break;
- case e_double: success = true; break;
- case e_long_double: success = true; break;
- }
-
- return success;
- }
- int
- Scalar::SInt(int fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return m_data.sint;
- case e_uint: return (int)m_data.uint;
- case e_slong: return (int)m_data.slong;
- case e_ulong: return (int)m_data.ulong;
- case e_slonglong: return (int)m_data.slonglong;
- case e_ulonglong: return (int)m_data.ulonglong;
- case e_float: return (int)m_data.flt;
- case e_double: return (int)m_data.dbl;
- case e_long_double: return (int)m_data.ldbl;
- }
- return fail_value;
- }
- unsigned int
- Scalar::UInt(unsigned int fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (unsigned int)m_data.sint;
- case e_uint: return (unsigned int)m_data.uint;
- case e_slong: return (unsigned int)m_data.slong;
- case e_ulong: return (unsigned int)m_data.ulong;
- case e_slonglong: return (unsigned int)m_data.slonglong;
- case e_ulonglong: return (unsigned int)m_data.ulonglong;
- case e_float: return (unsigned int)m_data.flt;
- case e_double: return (unsigned int)m_data.dbl;
- case e_long_double: return (unsigned int)m_data.ldbl;
- }
- return fail_value;
- }
- long
- Scalar::SLong(long fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (long)m_data.sint;
- case e_uint: return (long)m_data.uint;
- case e_slong: return (long)m_data.slong;
- case e_ulong: return (long)m_data.ulong;
- case e_slonglong: return (long)m_data.slonglong;
- case e_ulonglong: return (long)m_data.ulonglong;
- case e_float: return (long)m_data.flt;
- case e_double: return (long)m_data.dbl;
- case e_long_double: return (long)m_data.ldbl;
- }
- return fail_value;
- }
- unsigned long
- Scalar::ULong(unsigned long fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (unsigned long)m_data.sint;
- case e_uint: return (unsigned long)m_data.uint;
- case e_slong: return (unsigned long)m_data.slong;
- case e_ulong: return (unsigned long)m_data.ulong;
- case e_slonglong: return (unsigned long)m_data.slonglong;
- case e_ulonglong: return (unsigned long)m_data.ulonglong;
- case e_float: return (unsigned long)m_data.flt;
- case e_double: return (unsigned long)m_data.dbl;
- case e_long_double: return (unsigned long)m_data.ldbl;
- }
- return fail_value;
- }
- uint64_t
- Scalar::GetRawBits64(uint64_t fail_value) const
- {
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- return m_data.uint;
- case e_slong:
- case e_ulong:
- return m_data.ulong;
- case e_slonglong:
- case e_ulonglong:
- return m_data.ulonglong;
- case e_float:
- if (sizeof(m_data.flt) == sizeof(m_data.uint))
- return m_data.uint;
- else if (sizeof(m_data.flt) == sizeof(m_data.ulong))
- return m_data.ulong;
- else if (sizeof(m_data.flt) == sizeof(m_data.ulonglong))
- return m_data.ulonglong;
- break;
- case e_double:
- if (sizeof(m_data.dbl) == sizeof(m_data.uint))
- return m_data.uint;
- else if (sizeof(m_data.dbl) == sizeof(m_data.ulong))
- return m_data.ulong;
- else if (sizeof(m_data.dbl) == sizeof(m_data.ulonglong))
- return m_data.ulonglong;
- break;
- case e_long_double:
- if (sizeof(m_data.ldbl) == sizeof(m_data.uint))
- return m_data.uint;
- else if (sizeof(m_data.ldbl) == sizeof(m_data.ulong))
- return m_data.ulong;
- else if (sizeof(m_data.ldbl) == sizeof(m_data.ulonglong))
- return m_data.ulonglong;
- break;
- }
- return fail_value;
- }
- long long
- Scalar::SLongLong(long long fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (long long)m_data.sint;
- case e_uint: return (long long)m_data.uint;
- case e_slong: return (long long)m_data.slong;
- case e_ulong: return (long long)m_data.ulong;
- case e_slonglong: return (long long)m_data.slonglong;
- case e_ulonglong: return (long long)m_data.ulonglong;
- case e_float: return (long long)m_data.flt;
- case e_double: return (long long)m_data.dbl;
- case e_long_double: return (long long)m_data.ldbl;
- }
- return fail_value;
- }
- unsigned long long
- Scalar::ULongLong(unsigned long long fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (unsigned long long)m_data.sint;
- case e_uint: return (unsigned long long)m_data.uint;
- case e_slong: return (unsigned long long)m_data.slong;
- case e_ulong: return (unsigned long long)m_data.ulong;
- case e_slonglong: return (unsigned long long)m_data.slonglong;
- case e_ulonglong: return (unsigned long long)m_data.ulonglong;
- case e_float: return (unsigned long long)m_data.flt;
- case e_double: return (unsigned long long)m_data.dbl;
- case e_long_double: return (unsigned long long)m_data.ldbl;
- }
- return fail_value;
- }
- float
- Scalar::Float(float fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (float)m_data.sint;
- case e_uint: return (float)m_data.uint;
- case e_slong: return (float)m_data.slong;
- case e_ulong: return (float)m_data.ulong;
- case e_slonglong: return (float)m_data.slonglong;
- case e_ulonglong: return (float)m_data.ulonglong;
- case e_float: return (float)m_data.flt;
- case e_double: return (float)m_data.dbl;
- case e_long_double: return (float)m_data.ldbl;
- }
- return fail_value;
- }
- double
- Scalar::Double(double fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (double)m_data.sint;
- case e_uint: return (double)m_data.uint;
- case e_slong: return (double)m_data.slong;
- case e_ulong: return (double)m_data.ulong;
- case e_slonglong: return (double)m_data.slonglong;
- case e_ulonglong: return (double)m_data.ulonglong;
- case e_float: return (double)m_data.flt;
- case e_double: return (double)m_data.dbl;
- case e_long_double: return (double)m_data.ldbl;
- }
- return fail_value;
- }
- long double
- Scalar::LongDouble(long double fail_value) const
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: return (long double)m_data.sint;
- case e_uint: return (long double)m_data.uint;
- case e_slong: return (long double)m_data.slong;
- case e_ulong: return (long double)m_data.ulong;
- case e_slonglong: return (long double)m_data.slonglong;
- case e_ulonglong: return (long double)m_data.ulonglong;
- case e_float: return (long double)m_data.flt;
- case e_double: return (long double)m_data.dbl;
- case e_long_double: return (long double)m_data.ldbl;
- }
- return fail_value;
- }
- Scalar&
- Scalar::operator+= (const Scalar& rhs)
- {
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint: m_data.sint = a->m_data.sint + b->m_data.sint; break;
- case e_uint: m_data.uint = a->m_data.uint + b->m_data.uint; break;
- case e_slong: m_data.slong = a->m_data.slong + b->m_data.slong; break;
- case e_ulong: m_data.ulong = a->m_data.ulong + b->m_data.ulong; break;
- case e_slonglong: m_data.slonglong = a->m_data.slonglong + b->m_data.slonglong; break;
- case e_ulonglong: m_data.ulonglong = a->m_data.ulonglong + b->m_data.ulonglong; break;
- case e_float: m_data.flt = a->m_data.flt + b->m_data.flt; break;
- case e_double: m_data.dbl = a->m_data.dbl + b->m_data.dbl; break;
- case e_long_double: m_data.ldbl = a->m_data.ldbl + b->m_data.ldbl; break;
- }
- }
- return *this;
- }
- Scalar&
- Scalar::operator<<= (const Scalar& rhs)
- {
- switch (m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.sint <<= rhs.m_data.sint; break;
- case e_uint: m_data.sint <<= rhs.m_data.uint; break;
- case e_slong: m_data.sint <<= rhs.m_data.slong; break;
- case e_ulong: m_data.sint <<= rhs.m_data.ulong; break;
- case e_slonglong: m_data.sint <<= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.sint <<= rhs.m_data.ulonglong; break;
- }
- break;
- case e_uint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.uint <<= rhs.m_data.sint; break;
- case e_uint: m_data.uint <<= rhs.m_data.uint; break;
- case e_slong: m_data.uint <<= rhs.m_data.slong; break;
- case e_ulong: m_data.uint <<= rhs.m_data.ulong; break;
- case e_slonglong: m_data.uint <<= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.uint <<= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.slong <<= rhs.m_data.sint; break;
- case e_uint: m_data.slong <<= rhs.m_data.uint; break;
- case e_slong: m_data.slong <<= rhs.m_data.slong; break;
- case e_ulong: m_data.slong <<= rhs.m_data.ulong; break;
- case e_slonglong: m_data.slong <<= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.slong <<= rhs.m_data.ulonglong; break;
- }
- break;
- case e_ulong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulong <<= rhs.m_data.sint; break;
- case e_uint: m_data.ulong <<= rhs.m_data.uint; break;
- case e_slong: m_data.ulong <<= rhs.m_data.slong; break;
- case e_ulong: m_data.ulong <<= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulong <<= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulong <<= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slonglong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.slonglong <<= rhs.m_data.sint; break;
- case e_uint: m_data.slonglong <<= rhs.m_data.uint; break;
- case e_slong: m_data.slonglong <<= rhs.m_data.slong; break;
- case e_ulong: m_data.slonglong <<= rhs.m_data.ulong; break;
- case e_slonglong: m_data.slonglong <<= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.slonglong <<= rhs.m_data.ulonglong; break;
- }
- break;
- case e_ulonglong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulonglong <<= rhs.m_data.sint; break;
- case e_uint: m_data.ulonglong <<= rhs.m_data.uint; break;
- case e_slong: m_data.ulonglong <<= rhs.m_data.slong; break;
- case e_ulong: m_data.ulonglong <<= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulonglong <<= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulonglong <<= rhs.m_data.ulonglong; break;
- }
- break;
- }
- return *this;
- }
- bool
- Scalar::ShiftRightLogical(const Scalar& rhs)
- {
- switch (m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.uint >>= rhs.m_data.sint; break;
- case e_uint: m_data.uint >>= rhs.m_data.uint; break;
- case e_slong: m_data.uint >>= rhs.m_data.slong; break;
- case e_ulong: m_data.uint >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.uint >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.uint >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slong:
- case e_ulong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulong >>= rhs.m_data.sint; break;
- case e_uint: m_data.ulong >>= rhs.m_data.uint; break;
- case e_slong: m_data.ulong >>= rhs.m_data.slong; break;
- case e_ulong: m_data.ulong >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulong >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulong >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slonglong:
- case e_ulonglong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulonglong >>= rhs.m_data.sint; break;
- case e_uint: m_data.ulonglong >>= rhs.m_data.uint; break;
- case e_slong: m_data.ulonglong >>= rhs.m_data.slong; break;
- case e_ulong: m_data.ulonglong >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulonglong >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulonglong >>= rhs.m_data.ulonglong; break;
- }
- break;
- }
- return m_type != e_void;
- }
- Scalar&
- Scalar::operator>>= (const Scalar& rhs)
- {
- switch (m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.sint >>= rhs.m_data.sint; break;
- case e_uint: m_data.sint >>= rhs.m_data.uint; break;
- case e_slong: m_data.sint >>= rhs.m_data.slong; break;
- case e_ulong: m_data.sint >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.sint >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.sint >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_uint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.uint >>= rhs.m_data.sint; break;
- case e_uint: m_data.uint >>= rhs.m_data.uint; break;
- case e_slong: m_data.uint >>= rhs.m_data.slong; break;
- case e_ulong: m_data.uint >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.uint >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.uint >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.slong >>= rhs.m_data.sint; break;
- case e_uint: m_data.slong >>= rhs.m_data.uint; break;
- case e_slong: m_data.slong >>= rhs.m_data.slong; break;
- case e_ulong: m_data.slong >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.slong >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.slong >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_ulong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulong >>= rhs.m_data.sint; break;
- case e_uint: m_data.ulong >>= rhs.m_data.uint; break;
- case e_slong: m_data.ulong >>= rhs.m_data.slong; break;
- case e_ulong: m_data.ulong >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulong >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulong >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slonglong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.slonglong >>= rhs.m_data.sint; break;
- case e_uint: m_data.slonglong >>= rhs.m_data.uint; break;
- case e_slong: m_data.slonglong >>= rhs.m_data.slong; break;
- case e_ulong: m_data.slonglong >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.slonglong >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.slonglong >>= rhs.m_data.ulonglong; break;
- }
- break;
- case e_ulonglong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulonglong >>= rhs.m_data.sint; break;
- case e_uint: m_data.ulonglong >>= rhs.m_data.uint; break;
- case e_slong: m_data.ulonglong >>= rhs.m_data.slong; break;
- case e_ulong: m_data.ulonglong >>= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulonglong >>= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulonglong >>= rhs.m_data.ulonglong; break;
- }
- break;
- }
- return *this;
- }
- Scalar&
- Scalar::operator&= (const Scalar& rhs)
- {
- switch (m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.sint &= rhs.m_data.sint; break;
- case e_uint: m_data.sint &= rhs.m_data.uint; break;
- case e_slong: m_data.sint &= rhs.m_data.slong; break;
- case e_ulong: m_data.sint &= rhs.m_data.ulong; break;
- case e_slonglong: m_data.sint &= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.sint &= rhs.m_data.ulonglong; break;
- }
- break;
- case e_uint:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.uint &= rhs.m_data.sint; break;
- case e_uint: m_data.uint &= rhs.m_data.uint; break;
- case e_slong: m_data.uint &= rhs.m_data.slong; break;
- case e_ulong: m_data.uint &= rhs.m_data.ulong; break;
- case e_slonglong: m_data.uint &= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.uint &= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.slong &= rhs.m_data.sint; break;
- case e_uint: m_data.slong &= rhs.m_data.uint; break;
- case e_slong: m_data.slong &= rhs.m_data.slong; break;
- case e_ulong: m_data.slong &= rhs.m_data.ulong; break;
- case e_slonglong: m_data.slong &= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.slong &= rhs.m_data.ulonglong; break;
- }
- break;
- case e_ulong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.ulong &= rhs.m_data.sint; break;
- case e_uint: m_data.ulong &= rhs.m_data.uint; break;
- case e_slong: m_data.ulong &= rhs.m_data.slong; break;
- case e_ulong: m_data.ulong &= rhs.m_data.ulong; break;
- case e_slonglong: m_data.ulong &= rhs.m_data.slonglong; break;
- case e_ulonglong: m_data.ulong &= rhs.m_data.ulonglong; break;
- }
- break;
- case e_slonglong:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint: m_data.slonglong &= rhs.m_data.sint; break;
- case e_uint: m_data.slonglong &= rhs.m_data.uint; break;
- case e_slong: m_data.slonglong &= rhs.m_data.slong; break;
- case e_ulong: m_data.slonglong &= rhs.m_data.ulong; break;
- case e_slonglong: m_dat