You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
clang format apply
This commit is contained in:
@ -15,13 +15,11 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
|
||||
#ifndef MCS_DATA_CONDITION_H
|
||||
#define MCS_DATA_CONDITION_H
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
/*
|
||||
A subset of SQL Conditions related to data processing.
|
||||
SQLSTATE terminology is used for categories:
|
||||
@ -31,36 +29,39 @@ namespace datatypes
|
||||
*/
|
||||
class DataCondition
|
||||
{
|
||||
public:
|
||||
public:
|
||||
enum Code
|
||||
{
|
||||
// Code Value SQLSTATE
|
||||
S_SUCCESS = 0, // 00000
|
||||
W_STRING_DATA_RIGHT_TRUNCATION = 1 << 1, // 01004
|
||||
X_STRING_DATA_RIGHT_TRUNCATION = 1 << 16, // 22001
|
||||
X_NUMERIC_VALUE_OUT_OF_RANGE = 1 << 17, // 22003
|
||||
X_INVALID_CHARACTER_VALUE_FOR_CAST = 1 << 18, // 22018
|
||||
S_SUCCESS = 0, // 00000
|
||||
W_STRING_DATA_RIGHT_TRUNCATION = 1 << 1, // 01004
|
||||
X_STRING_DATA_RIGHT_TRUNCATION = 1 << 16, // 22001
|
||||
X_NUMERIC_VALUE_OUT_OF_RANGE = 1 << 17, // 22003
|
||||
X_INVALID_CHARACTER_VALUE_FOR_CAST = 1 << 18, // 22018
|
||||
};
|
||||
DataCondition()
|
||||
:mError(S_SUCCESS)
|
||||
{ }
|
||||
DataCondition(Code code)
|
||||
:mError(code)
|
||||
{ }
|
||||
DataCondition & operator|=(Code code)
|
||||
DataCondition() : mError(S_SUCCESS)
|
||||
{
|
||||
mError= (Code) (mError | code);
|
||||
}
|
||||
DataCondition(Code code) : mError(code)
|
||||
{
|
||||
}
|
||||
DataCondition& operator|=(Code code)
|
||||
{
|
||||
mError = (Code)(mError | code);
|
||||
return *this;
|
||||
}
|
||||
DataCondition operator&(Code rhs) const
|
||||
{
|
||||
return DataCondition((Code) (mError & rhs));
|
||||
return DataCondition((Code)(mError & rhs));
|
||||
}
|
||||
operator Code() const
|
||||
{
|
||||
return mError;
|
||||
}
|
||||
operator Code () const { return mError; }
|
||||
|
||||
// Adjust a sigened integer of any size to the range [-absMaxVal , +absMaxVal]
|
||||
template<typename T>
|
||||
void adjustSIntXRange(T & val, T absMaxVal)
|
||||
template <typename T>
|
||||
void adjustSIntXRange(T& val, T absMaxVal)
|
||||
{
|
||||
if (val > absMaxVal)
|
||||
{
|
||||
@ -74,10 +75,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
Code mError;
|
||||
};
|
||||
|
||||
} // namespace datatypes
|
||||
} // namespace datatypes
|
||||
|
||||
#endif // MCS_DATA_CONDITION_H
|
||||
#endif // MCS_DATA_CONDITION_H
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -26,13 +26,11 @@
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
|
||||
// Convert a positive floating point value to
|
||||
// a signed or unsigned integer with rounding
|
||||
// SRC - a floating point data type (float, double, float128_t)
|
||||
// DST - a signed or unsigned integer data type (int32_t, uint64_t, int128_t, etc)
|
||||
template<typename SRC, typename DST>
|
||||
template <typename SRC, typename DST>
|
||||
DST positiveXFloatToXIntRound(SRC value, DST limit)
|
||||
{
|
||||
SRC tmp = value + 0.5;
|
||||
@ -41,12 +39,11 @@ DST positiveXFloatToXIntRound(SRC value, DST limit)
|
||||
return static_cast<DST>(tmp);
|
||||
}
|
||||
|
||||
|
||||
// Convert a negative floating point value to
|
||||
// a signed integer with rounding
|
||||
// SRC - a floating point data type (float, double, float128_t)
|
||||
// DST - a signed integer data type (int32_t, int64_t, int128_t, etc)
|
||||
template<typename SRC, typename DST>
|
||||
template <typename SRC, typename DST>
|
||||
DST negativeXFloatToXIntRound(SRC value, DST limit)
|
||||
{
|
||||
SRC tmp = value - 0.5;
|
||||
@ -55,41 +52,32 @@ DST negativeXFloatToXIntRound(SRC value, DST limit)
|
||||
return static_cast<DST>(tmp);
|
||||
}
|
||||
|
||||
|
||||
// Convert a floating point value to ColumnStore int64_t
|
||||
// Magic values cannot be returned.
|
||||
template<typename SRC>
|
||||
template <typename SRC>
|
||||
int64_t xFloatToMCSSInt64Round(SRC value)
|
||||
{
|
||||
if (value > 0)
|
||||
return positiveXFloatToXIntRound<SRC, int64_t>(
|
||||
value,
|
||||
numeric_limits<int64_t>::max());
|
||||
return positiveXFloatToXIntRound<SRC, int64_t>(value, numeric_limits<int64_t>::max());
|
||||
if (value < 0)
|
||||
return negativeXFloatToXIntRound<SRC, int64_t>(
|
||||
value,
|
||||
numeric_limits<int64_t>::min() + 2);
|
||||
return negativeXFloatToXIntRound<SRC, int64_t>(value, numeric_limits<int64_t>::min() + 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Convert a floating point value to ColumnStore uint64_t
|
||||
// Magic values cannot be returned.
|
||||
template<typename SRC>
|
||||
template <typename SRC>
|
||||
uint64_t xFloatToMCSUInt64Round(SRC value)
|
||||
{
|
||||
if (value > 0)
|
||||
return positiveXFloatToXIntRound<SRC, uint64_t>(
|
||||
value,
|
||||
numeric_limits<uint64_t>::max() - 2);
|
||||
return positiveXFloatToXIntRound<SRC, uint64_t>(value, numeric_limits<uint64_t>::max() - 2);
|
||||
if (value < 0)
|
||||
return negativeXFloatToXIntRound<SRC, uint64_t>(value, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end of namespace datatypes
|
||||
|
||||
} //end of namespace datatypes
|
||||
|
||||
#endif // MCS_DATATYPE_BASIC_H_INCLUDED
|
||||
#endif // MCS_DATATYPE_BASIC_H_INCLUDED
|
||||
// vim:ts=2 sw=2:
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -23,17 +23,21 @@
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
class TDouble
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
double mValue;
|
||||
public:
|
||||
TDouble(): mValue(0) { }
|
||||
|
||||
explicit TDouble(double value): mValue(value) { }
|
||||
public:
|
||||
TDouble() : mValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator double () const
|
||||
explicit TDouble(double value) : mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator double() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
@ -49,8 +53,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end of namespace datatypes
|
||||
|
||||
} //end of namespace datatypes
|
||||
|
||||
#endif // MCS_DOUBLE_H_INCLUDED
|
||||
#endif // MCS_DOUBLE_H_INCLUDED
|
||||
// vim:ts=2 sw=2:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,8 +14,8 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
*/
|
||||
MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -24,98 +24,93 @@
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
uint8_t TSInt128::printPodParts(char* buf,
|
||||
const int128_t& high,
|
||||
const int128_t& mid,
|
||||
const int128_t& low) const
|
||||
{
|
||||
char* p = buf;
|
||||
// pod[0] is low 8 bytes, pod[1] is high 8 bytes
|
||||
const uint64_t* high_pod = reinterpret_cast<const uint64_t*>(&high);
|
||||
const uint64_t* mid_pod = reinterpret_cast<const uint64_t*>(&mid);
|
||||
const uint64_t* low_pod = reinterpret_cast<const uint64_t*>(&low);
|
||||
uint8_t TSInt128::printPodParts(char* buf, const int128_t& high, const int128_t& mid,
|
||||
const int128_t& low) const
|
||||
{
|
||||
char* p = buf;
|
||||
// pod[0] is low 8 bytes, pod[1] is high 8 bytes
|
||||
const uint64_t* high_pod = reinterpret_cast<const uint64_t*>(&high);
|
||||
const uint64_t* mid_pod = reinterpret_cast<const uint64_t*>(&mid);
|
||||
const uint64_t* low_pod = reinterpret_cast<const uint64_t*>(&low);
|
||||
|
||||
if (high_pod[0] != 0)
|
||||
{
|
||||
p += sprintf(p, "%lu", high_pod[0]);
|
||||
p += sprintf(p, "%019lu", mid_pod[0]);
|
||||
p += sprintf(p, "%019lu", low_pod[0]);
|
||||
}
|
||||
else if (mid_pod[0] != 0)
|
||||
{
|
||||
p += sprintf(p, "%lu", mid_pod[0]);
|
||||
p += sprintf(p, "%019lu", low_pod[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
p += sprintf(p, "%lu", low_pod[0]);
|
||||
}
|
||||
return p - buf;
|
||||
if (high_pod[0] != 0)
|
||||
{
|
||||
p += sprintf(p, "%lu", high_pod[0]);
|
||||
p += sprintf(p, "%019lu", mid_pod[0]);
|
||||
p += sprintf(p, "%019lu", low_pod[0]);
|
||||
}
|
||||
else if (mid_pod[0] != 0)
|
||||
{
|
||||
p += sprintf(p, "%lu", mid_pod[0]);
|
||||
p += sprintf(p, "%019lu", low_pod[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
p += sprintf(p, "%lu", low_pod[0]);
|
||||
}
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
// This method writes unsigned integer representation of TSInt128
|
||||
uint8_t TSInt128::writeIntPart(const int128_t& x, char* buf, const uint8_t buflen) const
|
||||
{
|
||||
char* p = buf;
|
||||
int128_t high = 0, mid = 0, low = 0;
|
||||
uint64_t maxUint64divisor = 10000000000000000000ULL;
|
||||
|
||||
low = x % maxUint64divisor;
|
||||
int128_t value = x / maxUint64divisor;
|
||||
mid = value % maxUint64divisor;
|
||||
high = value / maxUint64divisor;
|
||||
|
||||
p += printPodParts(p, high, mid, low);
|
||||
uint8_t written = p - buf;
|
||||
if (buflen <= written)
|
||||
{
|
||||
throw logging::QueryDataExcept("TSInt128::writeIntPart() char buffer overflow.", logging::formatErr);
|
||||
}
|
||||
|
||||
// This method writes unsigned integer representation of TSInt128
|
||||
uint8_t TSInt128::writeIntPart(const int128_t& x,
|
||||
char* buf,
|
||||
const uint8_t buflen) const
|
||||
return written;
|
||||
}
|
||||
|
||||
// conversion to std::string
|
||||
std::string TSInt128::toString() const
|
||||
{
|
||||
if (isNull())
|
||||
{
|
||||
char* p = buf;
|
||||
int128_t high = 0, mid = 0, low = 0;
|
||||
uint64_t maxUint64divisor = 10000000000000000000ULL;
|
||||
|
||||
low = x % maxUint64divisor;
|
||||
int128_t value = x / maxUint64divisor;
|
||||
mid = value % maxUint64divisor;
|
||||
high = value / maxUint64divisor;
|
||||
|
||||
p += printPodParts(p, high, mid, low);
|
||||
uint8_t written = p - buf;
|
||||
if (buflen <= written)
|
||||
{
|
||||
throw logging::QueryDataExcept("TSInt128::writeIntPart() char buffer overflow.",
|
||||
logging::formatErr);
|
||||
}
|
||||
|
||||
return written;
|
||||
return std::string("NULL");
|
||||
}
|
||||
|
||||
// conversion to std::string
|
||||
std::string TSInt128::toString() const
|
||||
if (isEmpty())
|
||||
{
|
||||
if (isNull())
|
||||
{
|
||||
return std::string("NULL");
|
||||
}
|
||||
return std::string("EMPTY");
|
||||
}
|
||||
|
||||
if (isEmpty())
|
||||
{
|
||||
return std::string("EMPTY");
|
||||
}
|
||||
|
||||
int128_t tempValue = s128Value;
|
||||
char buf[TSInt128::MAXLENGTH16BYTES];
|
||||
uint8_t left = sizeof(buf);
|
||||
char* p = buf;
|
||||
// sign
|
||||
if (tempValue < static_cast<int128_t>(0))
|
||||
{
|
||||
*p++ = '-';
|
||||
tempValue *= -1;
|
||||
left--;
|
||||
}
|
||||
// integer part
|
||||
// reduce the size by one to account for \0
|
||||
int128_t tempValue = s128Value;
|
||||
char buf[TSInt128::MAXLENGTH16BYTES];
|
||||
uint8_t left = sizeof(buf);
|
||||
char* p = buf;
|
||||
// sign
|
||||
if (tempValue < static_cast<int128_t>(0))
|
||||
{
|
||||
*p++ = '-';
|
||||
tempValue *= -1;
|
||||
left--;
|
||||
p += writeIntPart(tempValue, p, left);
|
||||
*p = '\0';
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
// integer part
|
||||
// reduce the size by one to account for \0
|
||||
left--;
|
||||
p += writeIntPart(tempValue, p, left);
|
||||
*p = '\0';
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const TSInt128& x)
|
||||
{
|
||||
os << x.toString();
|
||||
return os;
|
||||
}
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
} // end of namespace datatypes
|
||||
std::ostream& operator<<(std::ostream& os, const TSInt128& x)
|
||||
{
|
||||
os << x.toString();
|
||||
return os;
|
||||
}
|
||||
|
||||
} // end of namespace datatypes
|
||||
// vim:ts=2 sw=2:
|
||||
|
@ -28,100 +28,73 @@
|
||||
|
||||
// Inline asm has three argument lists: output, input and clobber list
|
||||
#ifdef __aarch64__
|
||||
#define MACRO_VALUE_PTR_128(dst, \
|
||||
dst_restrictions, \
|
||||
src, \
|
||||
src_restrictions, \
|
||||
clobb) \
|
||||
::memcpy((dst), &(src), sizeof(int128_t));
|
||||
#define MACRO_PTR_PTR_128(dst, \
|
||||
dst_restrictions, \
|
||||
src, \
|
||||
src_restrictions, \
|
||||
clobb) \
|
||||
::memcpy((dst), (src), sizeof(int128_t));
|
||||
#define MACRO_VALUE_PTR_128(dst, dst_restrictions, src, src_restrictions, clobb) \
|
||||
::memcpy((dst), &(src), sizeof(int128_t));
|
||||
#define MACRO_PTR_PTR_128(dst, dst_restrictions, src, src_restrictions, clobb) \
|
||||
::memcpy((dst), (src), sizeof(int128_t));
|
||||
#elif defined(__GNUC__) && (__GNUC___ > 7) || defined(__clang__)
|
||||
#define MACRO_VALUE_PTR_128(dst, \
|
||||
dst_restrictions, \
|
||||
src, \
|
||||
src_restrictions, \
|
||||
clobb) \
|
||||
__asm__ volatile("movups %1,%0" \
|
||||
:dst_restrictions ( *(dst) ) \
|
||||
:src_restrictions ( (src) ) \
|
||||
:clobb \
|
||||
);
|
||||
#define MACRO_PTR_PTR_128(dst, \
|
||||
dst_restrictions, \
|
||||
src, \
|
||||
src_restrictions, \
|
||||
clobb) \
|
||||
::memcpy((dst), (src), sizeof(int128_t));
|
||||
#define MACRO_VALUE_PTR_128(dst, dst_restrictions, src, src_restrictions, clobb) \
|
||||
__asm__ volatile("movups %1,%0" : dst_restrictions(*(dst)) : src_restrictions((src)) : clobb);
|
||||
#define MACRO_PTR_PTR_128(dst, dst_restrictions, src, src_restrictions, clobb) \
|
||||
::memcpy((dst), (src), sizeof(int128_t));
|
||||
|
||||
#else
|
||||
#define MACRO_VALUE_PTR_128(dst, \
|
||||
dst_restrictions, \
|
||||
src, \
|
||||
src_restrictions, \
|
||||
clobb) \
|
||||
__asm__ volatile("movups %1,%0" \
|
||||
:dst_restrictions ( *(dst) ) \
|
||||
:src_restrictions ( (src) ) \
|
||||
:clobb \
|
||||
);
|
||||
#define MACRO_PTR_PTR_128(dst, \
|
||||
dst_restrictions, \
|
||||
src, \
|
||||
src_restrictions, \
|
||||
clobb) \
|
||||
__asm__ volatile("movdqu %1,%%xmm0;" \
|
||||
"movups %%xmm0,%0;" \
|
||||
:dst_restrictions ( *(dst) ) \
|
||||
:src_restrictions ( *(src) ) \
|
||||
:"memory", clobb \
|
||||
);
|
||||
#define MACRO_VALUE_PTR_128(dst, dst_restrictions, src, src_restrictions, clobb) \
|
||||
__asm__ volatile("movups %1,%0" : dst_restrictions(*(dst)) : src_restrictions((src)) : clobb);
|
||||
#define MACRO_PTR_PTR_128(dst, dst_restrictions, src, src_restrictions, clobb) \
|
||||
__asm__ volatile( \
|
||||
"movdqu %1,%%xmm0;" \
|
||||
"movups %%xmm0,%0;" \
|
||||
: dst_restrictions(*(dst)) \
|
||||
: src_restrictions(*(src)) \
|
||||
: "memory", clobb);
|
||||
#endif
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
using int128_t = __int128;
|
||||
using uint128_t = unsigned __int128;
|
||||
|
||||
|
||||
// Type traits
|
||||
template <typename T>
|
||||
struct is_allowed_numeric {
|
||||
struct is_allowed_numeric
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_allowed_numeric<int> {
|
||||
struct is_allowed_numeric<int>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_allowed_numeric<int128_t> {
|
||||
struct is_allowed_numeric<int128_t>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_int128_t {
|
||||
struct is_int128_t
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_int128_t<int128_t> {
|
||||
template <>
|
||||
struct is_int128_t<int128_t>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_uint128_t {
|
||||
struct is_uint128_t
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_uint128_t<uint128_t> {
|
||||
template <>
|
||||
struct is_uint128_t<uint128_t>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
@ -132,218 +105,223 @@ inline int128_t abs(int128_t x)
|
||||
|
||||
class TSInt128
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t MAXLENGTH16BYTES = 42;
|
||||
static constexpr int128_t NullValue = int128_t(0x8000000000000000LL) << 64;
|
||||
static constexpr int128_t EmptyValue = (int128_t(0x8000000000000000LL) << 64) + 1;
|
||||
public:
|
||||
static constexpr uint8_t MAXLENGTH16BYTES = 42;
|
||||
static constexpr int128_t NullValue = int128_t(0x8000000000000000LL) << 64;
|
||||
static constexpr int128_t EmptyValue = (int128_t(0x8000000000000000LL) << 64) + 1;
|
||||
|
||||
// A variety of ctors for aligned and unaligned arguments
|
||||
TSInt128(): s128Value(0) { }
|
||||
// A variety of ctors for aligned and unaligned arguments
|
||||
TSInt128() : s128Value(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Copy ctor
|
||||
TSInt128(const TSInt128& other): s128Value(other.s128Value) { }
|
||||
// Copy ctor
|
||||
TSInt128(const TSInt128& other) : s128Value(other.s128Value)
|
||||
{
|
||||
}
|
||||
|
||||
TSInt128& operator=(const TSInt128& other)
|
||||
{
|
||||
s128Value = other.s128Value;
|
||||
return *this;
|
||||
}
|
||||
TSInt128& operator=(const TSInt128& other)
|
||||
{
|
||||
s128Value = other.s128Value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// aligned argument
|
||||
explicit TSInt128(const int128_t& x) { s128Value = x; }
|
||||
// aligned argument
|
||||
explicit TSInt128(const int128_t& x)
|
||||
{
|
||||
s128Value = x;
|
||||
}
|
||||
|
||||
// unaligned argument
|
||||
explicit TSInt128(const int128_t* x) { assignPtrPtr(&s128Value, x); }
|
||||
// unaligned argument
|
||||
explicit TSInt128(const int128_t* x)
|
||||
{
|
||||
assignPtrPtr(&s128Value, x);
|
||||
}
|
||||
|
||||
// unaligned argument
|
||||
explicit TSInt128(const unsigned char* x) { assignPtrPtr(&s128Value, x); }
|
||||
// unaligned argument
|
||||
explicit TSInt128(const unsigned char* x)
|
||||
{
|
||||
assignPtrPtr(&s128Value, x);
|
||||
}
|
||||
|
||||
// Method returns max length of a string representation
|
||||
static constexpr uint8_t maxLength()
|
||||
{
|
||||
return TSInt128::MAXLENGTH16BYTES;
|
||||
}
|
||||
// Method returns max length of a string representation
|
||||
static constexpr uint8_t maxLength()
|
||||
{
|
||||
return TSInt128::MAXLENGTH16BYTES;
|
||||
}
|
||||
|
||||
// Checks if the value is NULL
|
||||
inline bool isNull() const
|
||||
{
|
||||
return s128Value == NullValue;
|
||||
}
|
||||
// Checks if the value is NULL
|
||||
inline bool isNull() const
|
||||
{
|
||||
return s128Value == NullValue;
|
||||
}
|
||||
|
||||
// Checks if the value is Empty
|
||||
inline bool isEmpty() const
|
||||
{
|
||||
return s128Value == EmptyValue;
|
||||
}
|
||||
// Checks if the value is Empty
|
||||
inline bool isEmpty() const
|
||||
{
|
||||
return s128Value == EmptyValue;
|
||||
}
|
||||
|
||||
// The method copies 16 bytes from one memory cell
|
||||
// into another using memcpy or SIMD.
|
||||
// memcpy in gcc >= 7 is replaced with SIMD instructions
|
||||
template <typename D, typename S>
|
||||
static inline void assignPtrPtr(D* dst, const S* src)
|
||||
{
|
||||
MACRO_PTR_PTR_128(dst, "=m", src, "m", "xmm0")
|
||||
}
|
||||
// The method copies 16 bytes from one memory cell
|
||||
// into another using memcpy or SIMD.
|
||||
// memcpy in gcc >= 7 is replaced with SIMD instructions
|
||||
template <typename D, typename S>
|
||||
static inline void assignPtrPtr(D* dst, const S* src)
|
||||
{
|
||||
MACRO_PTR_PTR_128(dst, "=m", src, "m", "xmm0")
|
||||
}
|
||||
|
||||
template <typename D>
|
||||
static inline void storeUnaligned(D* dst, const int128_t& src)
|
||||
{
|
||||
MACRO_VALUE_PTR_128(dst, "=m", src, "x", "memory")
|
||||
}
|
||||
template <typename D>
|
||||
static inline void storeUnaligned(D* dst, const int128_t& src)
|
||||
{
|
||||
MACRO_VALUE_PTR_128(dst, "=m", src, "x", "memory")
|
||||
}
|
||||
|
||||
// operators
|
||||
template<typename T,
|
||||
typename = std::enable_if<is_allowed_numeric<T>::value> >
|
||||
inline bool operator<(const T& x) const
|
||||
{
|
||||
return s128Value < static_cast<int128_t>(x);
|
||||
}
|
||||
// operators
|
||||
template <typename T, typename = std::enable_if<is_allowed_numeric<T>::value> >
|
||||
inline bool operator<(const T& x) const
|
||||
{
|
||||
return s128Value < static_cast<int128_t>(x);
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename = std::enable_if<is_allowed_numeric<T>::value> >
|
||||
inline bool operator==(const T& x) const
|
||||
{
|
||||
return s128Value == static_cast<int128_t>(x);
|
||||
}
|
||||
template <typename T, typename = std::enable_if<is_allowed_numeric<T>::value> >
|
||||
inline bool operator==(const T& x) const
|
||||
{
|
||||
return s128Value == static_cast<int128_t>(x);
|
||||
}
|
||||
|
||||
inline operator double() const
|
||||
{
|
||||
return toDouble();
|
||||
}
|
||||
inline operator double() const
|
||||
{
|
||||
return toDouble();
|
||||
}
|
||||
|
||||
inline double toDouble() const
|
||||
{
|
||||
return static_cast<double>(s128Value);
|
||||
}
|
||||
inline double toDouble() const
|
||||
{
|
||||
return static_cast<double>(s128Value);
|
||||
}
|
||||
|
||||
inline operator long double() const
|
||||
{
|
||||
return toLongDouble();
|
||||
}
|
||||
inline operator long double() const
|
||||
{
|
||||
return toLongDouble();
|
||||
}
|
||||
|
||||
inline long double toLongDouble() const
|
||||
{
|
||||
return static_cast<long double>(s128Value);
|
||||
}
|
||||
inline long double toLongDouble() const
|
||||
{
|
||||
return static_cast<long double>(s128Value);
|
||||
}
|
||||
|
||||
inline operator int32_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(INT32_MAX))
|
||||
return INT32_MAX;
|
||||
if (s128Value < static_cast<int128_t>(INT32_MIN))
|
||||
return INT32_MIN;
|
||||
inline operator int32_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(INT32_MAX))
|
||||
return INT32_MAX;
|
||||
if (s128Value < static_cast<int128_t>(INT32_MIN))
|
||||
return INT32_MIN;
|
||||
|
||||
return static_cast<int32_t>(s128Value);
|
||||
}
|
||||
return static_cast<int32_t>(s128Value);
|
||||
}
|
||||
|
||||
inline operator uint32_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(UINT32_MAX))
|
||||
return UINT32_MAX;
|
||||
if (s128Value < 0)
|
||||
return 0;
|
||||
inline operator uint32_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(UINT32_MAX))
|
||||
return UINT32_MAX;
|
||||
if (s128Value < 0)
|
||||
return 0;
|
||||
|
||||
return static_cast<uint32_t>(s128Value);
|
||||
}
|
||||
return static_cast<uint32_t>(s128Value);
|
||||
}
|
||||
|
||||
inline operator int64_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(INT64_MAX))
|
||||
return INT64_MAX;
|
||||
if (s128Value < static_cast<int128_t>(INT64_MIN))
|
||||
return INT64_MIN;
|
||||
inline operator int64_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(INT64_MAX))
|
||||
return INT64_MAX;
|
||||
if (s128Value < static_cast<int128_t>(INT64_MIN))
|
||||
return INT64_MIN;
|
||||
|
||||
return static_cast<int64_t>(s128Value);
|
||||
}
|
||||
return static_cast<int64_t>(s128Value);
|
||||
}
|
||||
|
||||
inline operator uint64_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(UINT64_MAX))
|
||||
return UINT64_MAX;
|
||||
if (s128Value < 0)
|
||||
return 0;
|
||||
inline operator uint64_t() const
|
||||
{
|
||||
if (s128Value > static_cast<int128_t>(UINT64_MAX))
|
||||
return UINT64_MAX;
|
||||
if (s128Value < 0)
|
||||
return 0;
|
||||
|
||||
return static_cast<uint64_t>(s128Value);
|
||||
}
|
||||
return static_cast<uint64_t>(s128Value);
|
||||
}
|
||||
|
||||
inline operator TFloat128() const
|
||||
{
|
||||
return toTFloat128();
|
||||
}
|
||||
inline operator TFloat128() const
|
||||
{
|
||||
return toTFloat128();
|
||||
}
|
||||
|
||||
// unaligned argument
|
||||
inline TSInt128& operator=(const int128_t* x)
|
||||
{
|
||||
assignPtrPtr(&s128Value, x);
|
||||
return *this;
|
||||
}
|
||||
// unaligned argument
|
||||
inline TSInt128& operator=(const int128_t* x)
|
||||
{
|
||||
assignPtrPtr(&s128Value, x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TSInt128 operator%(const int64_t& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value % rhs);
|
||||
}
|
||||
inline TSInt128 operator%(const int64_t& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value % rhs);
|
||||
}
|
||||
|
||||
inline TSInt128 operator%(const int128_t& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value % rhs);
|
||||
}
|
||||
inline TSInt128 operator%(const int128_t& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value % rhs);
|
||||
}
|
||||
|
||||
inline TSInt128 operator*(const TSInt128& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value * rhs.s128Value);
|
||||
}
|
||||
inline TSInt128 operator*(const TSInt128& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value * rhs.s128Value);
|
||||
}
|
||||
|
||||
inline TSInt128 operator+(const TSInt128& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value + rhs.s128Value);
|
||||
}
|
||||
inline TSInt128 operator+(const TSInt128& rhs) const
|
||||
{
|
||||
return TSInt128(s128Value + rhs.s128Value);
|
||||
}
|
||||
|
||||
inline bool operator>(const TSInt128& rhs) const
|
||||
{
|
||||
return s128Value > rhs.s128Value;
|
||||
}
|
||||
inline bool operator>(const TSInt128& rhs) const
|
||||
{
|
||||
return s128Value > rhs.s128Value;
|
||||
}
|
||||
|
||||
inline bool operator<(const TSInt128& rhs) const
|
||||
{
|
||||
return s128Value < rhs.s128Value;
|
||||
}
|
||||
inline bool operator<(const TSInt128& rhs) const
|
||||
{
|
||||
return s128Value < rhs.s128Value;
|
||||
}
|
||||
|
||||
inline bool operator!=(const TSInt128& rhs) const
|
||||
{
|
||||
return s128Value != rhs.getValue();
|
||||
}
|
||||
inline bool operator!=(const TSInt128& rhs) const
|
||||
{
|
||||
return s128Value != rhs.getValue();
|
||||
}
|
||||
|
||||
inline TFloat128 toTFloat128() const
|
||||
{
|
||||
return TFloat128(s128Value);
|
||||
}
|
||||
inline TFloat128 toTFloat128() const
|
||||
{
|
||||
return TFloat128(s128Value);
|
||||
}
|
||||
|
||||
inline const int128_t& getValue() const
|
||||
{
|
||||
return s128Value;
|
||||
}
|
||||
inline const int128_t& getValue() const
|
||||
{
|
||||
return s128Value;
|
||||
}
|
||||
|
||||
// print int128_t parts represented as PODs
|
||||
uint8_t printPodParts(char* buf,
|
||||
const int128_t& high,
|
||||
const int128_t& mid,
|
||||
const int128_t& low) const;
|
||||
// print int128_t parts represented as PODs
|
||||
uint8_t printPodParts(char* buf, const int128_t& high, const int128_t& mid, const int128_t& low) const;
|
||||
|
||||
// writes integer part of dec into a buffer
|
||||
uint8_t writeIntPart(const int128_t& x,
|
||||
char* buf,
|
||||
const uint8_t buflen) const;
|
||||
// writes integer part of dec into a buffer
|
||||
uint8_t writeIntPart(const int128_t& x, char* buf, const uint8_t buflen) const;
|
||||
|
||||
// string representation of TSInt128
|
||||
std::string toString() const;
|
||||
// string representation of TSInt128
|
||||
std::string toString() const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const TSInt128& x);
|
||||
friend std::ostream& operator<<(std::ostream& os, const TSInt128& x);
|
||||
|
||||
int128_t s128Value;
|
||||
}; // end of class
|
||||
int128_t s128Value;
|
||||
}; // end of class
|
||||
|
||||
} // end of namespace datatypes
|
||||
|
||||
} //end of namespace datatypes
|
||||
|
||||
#endif // MCS_TSINT128_H_INCLUDED
|
||||
#endif // MCS_TSINT128_H_INCLUDED
|
||||
// vim:ts=2 sw=2:
|
||||
|
@ -14,8 +14,8 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
*/
|
||||
MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef MCS_INT64_H_INCLUDED
|
||||
#define MCS_INT64_H_INCLUDED
|
||||
|
||||
@ -23,155 +23,162 @@
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
|
||||
class TNullFlag
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
bool mIsNull;
|
||||
public:
|
||||
explicit TNullFlag(bool val) :mIsNull(val) { }
|
||||
|
||||
public:
|
||||
explicit TNullFlag(bool val) : mIsNull(val)
|
||||
{
|
||||
}
|
||||
bool isNull() const
|
||||
{
|
||||
return mIsNull;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class TUInt64
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
uint64_t mValue;
|
||||
public:
|
||||
TUInt64(): mValue(0) { }
|
||||
|
||||
explicit TUInt64(uint64_t value): mValue(value) { }
|
||||
public:
|
||||
TUInt64() : mValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator uint64_t () const
|
||||
explicit TUInt64(uint64_t value) : mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator uint64_t() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void store(uint8_t* dst) const
|
||||
{
|
||||
*(uint64_t*) dst = mValue;
|
||||
*(uint64_t*)dst = mValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class TSInt64
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
int64_t mValue;
|
||||
public:
|
||||
TSInt64(): mValue(0) { }
|
||||
|
||||
explicit TSInt64(int64_t value): mValue(value) { }
|
||||
public:
|
||||
TSInt64() : mValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator int64_t () const
|
||||
explicit TSInt64(int64_t value) : mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator int64_t() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
explicit operator uint64_t () const
|
||||
explicit operator uint64_t() const
|
||||
{
|
||||
return mValue < 0 ? 0 : static_cast<uint64_t>(mValue);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TUInt64Null: public TUInt64, public TNullFlag
|
||||
class TUInt64Null : public TUInt64, public TNullFlag
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TUInt64Null() : TNullFlag(true)
|
||||
{
|
||||
}
|
||||
|
||||
TUInt64Null(): TNullFlag(true) { }
|
||||
explicit TUInt64Null(uint64_t value, bool isNull = false) : TUInt64(value), TNullFlag(isNull)
|
||||
{
|
||||
}
|
||||
|
||||
explicit TUInt64Null(uint64_t value, bool isNull = false):
|
||||
TUInt64(value), TNullFlag(isNull)
|
||||
{ }
|
||||
|
||||
explicit operator uint64_t () const
|
||||
explicit operator uint64_t() const
|
||||
{
|
||||
idbassert(!mIsNull);
|
||||
return mValue;
|
||||
}
|
||||
uint64_t nullSafeValue(bool & isNullRef) const
|
||||
uint64_t nullSafeValue(bool& isNullRef) const
|
||||
{
|
||||
return (isNullRef = isNull()) ? 0 : mValue;
|
||||
}
|
||||
|
||||
TUInt64Null operator&(const TUInt64Null &rhs) const
|
||||
TUInt64Null operator&(const TUInt64Null& rhs) const
|
||||
{
|
||||
return TUInt64Null(mValue & rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TUInt64Null operator|(const TUInt64Null &rhs) const
|
||||
TUInt64Null operator|(const TUInt64Null& rhs) const
|
||||
{
|
||||
return TUInt64Null(mValue | rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TUInt64Null operator^(const TUInt64Null &rhs) const
|
||||
TUInt64Null operator^(const TUInt64Null& rhs) const
|
||||
{
|
||||
return TUInt64Null(mValue ^ rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TUInt64Null MariaDBShiftLeft(const TUInt64Null &rhs) const
|
||||
TUInt64Null MariaDBShiftLeft(const TUInt64Null& rhs) const
|
||||
{
|
||||
return TUInt64Null(rhs.mValue >= 64 ? 0 : mValue << rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TUInt64Null MariaDBShiftRight(const TUInt64Null &rhs) const
|
||||
TUInt64Null MariaDBShiftRight(const TUInt64Null& rhs) const
|
||||
{
|
||||
return TUInt64Null(rhs.mValue >= 64 ? 0 : mValue >> rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class TSInt64Null: public TSInt64, public TNullFlag
|
||||
class TSInt64Null : public TSInt64, public TNullFlag
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TSInt64Null() : TNullFlag(true)
|
||||
{
|
||||
}
|
||||
|
||||
TSInt64Null(): TNullFlag(true) { }
|
||||
explicit TSInt64Null(int64_t value, bool isNull = false) : TSInt64(value), TNullFlag(isNull)
|
||||
{
|
||||
}
|
||||
|
||||
explicit TSInt64Null(int64_t value, bool isNull = false):
|
||||
TSInt64(value), TNullFlag(isNull)
|
||||
{ }
|
||||
|
||||
explicit operator int64_t () const
|
||||
explicit operator int64_t() const
|
||||
{
|
||||
idbassert(!mIsNull);
|
||||
return mValue;
|
||||
}
|
||||
|
||||
int64_t nullSafeValue(bool & isNullRef) const
|
||||
int64_t nullSafeValue(bool& isNullRef) const
|
||||
{
|
||||
return (isNullRef = isNull()) ? 0 : mValue;
|
||||
}
|
||||
|
||||
TSInt64Null operator&(const TSInt64Null &rhs) const
|
||||
TSInt64Null operator&(const TSInt64Null& rhs) const
|
||||
{
|
||||
return TSInt64Null(mValue & rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TSInt64Null operator|(const TSInt64Null &rhs) const
|
||||
TSInt64Null operator|(const TSInt64Null& rhs) const
|
||||
{
|
||||
return TSInt64Null(mValue | rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TSInt64Null operator^(const TSInt64Null &rhs) const
|
||||
TSInt64Null operator^(const TSInt64Null& rhs) const
|
||||
{
|
||||
return TSInt64Null(mValue ^ rhs.mValue, mIsNull || rhs.mIsNull);
|
||||
}
|
||||
TSInt64Null MariaDBShiftLeft(const TUInt64Null &rhs) const
|
||||
TSInt64Null MariaDBShiftLeft(const TUInt64Null& rhs) const
|
||||
{
|
||||
if (isNull() || rhs.isNull())
|
||||
return TSInt64Null();
|
||||
return TSInt64Null((uint64_t) rhs >= 64 ? 0 : mValue << (uint64_t) rhs, false);
|
||||
return TSInt64Null((uint64_t)rhs >= 64 ? 0 : mValue << (uint64_t)rhs, false);
|
||||
}
|
||||
TSInt64Null MariaDBShiftRight(const TUInt64Null &rhs) const
|
||||
TSInt64Null MariaDBShiftRight(const TUInt64Null& rhs) const
|
||||
{
|
||||
if (isNull() || rhs.isNull())
|
||||
return TSInt64Null();
|
||||
return TSInt64Null((uint64_t) rhs >= 64 ? 0 : mValue >> (uint64_t) rhs, false);
|
||||
return TSInt64Null((uint64_t)rhs >= 64 ? 0 : mValue >> (uint64_t)rhs, false);
|
||||
}
|
||||
};
|
||||
|
||||
} // end of namespace datatypes
|
||||
|
||||
} //end of namespace datatypes
|
||||
|
||||
#endif // MCS_INT64_H_INCLUDED
|
||||
#endif // MCS_INT64_H_INCLUDED
|
||||
// vim:ts=2 sw=2:
|
||||
|
@ -23,17 +23,21 @@
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
class TLongDouble
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
long double mValue;
|
||||
public:
|
||||
TLongDouble(): mValue(0) { }
|
||||
|
||||
explicit TLongDouble(long double value): mValue(value) { }
|
||||
public:
|
||||
TLongDouble() : mValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator long double () const
|
||||
explicit TLongDouble(long double value) : mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator long double() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
@ -49,8 +53,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end of namespace datatypes
|
||||
|
||||
} //end of namespace datatypes
|
||||
|
||||
#endif // MCS_LONGDOUBLE_H_INCLUDED
|
||||
#endif // MCS_LONGDOUBLE_H_INCLUDED
|
||||
// vim:ts=2 sw=2:
|
||||
|
@ -22,18 +22,24 @@
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits
|
||||
{
|
||||
static constexpr T min() { return std::numeric_limits<T>::min(); }
|
||||
static constexpr T max() { return std::numeric_limits<T>::max(); }
|
||||
static constexpr T min()
|
||||
{
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
static constexpr T max()
|
||||
{
|
||||
return std::numeric_limits<T>::max();
|
||||
}
|
||||
};
|
||||
|
||||
using int128_t = __int128;
|
||||
using uint128_t = unsigned __int128;
|
||||
|
||||
template<> struct numeric_limits<int128_t>
|
||||
template <>
|
||||
struct numeric_limits<int128_t>
|
||||
{
|
||||
static constexpr int128_t min()
|
||||
{
|
||||
@ -45,7 +51,8 @@ template<> struct numeric_limits<int128_t>
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct numeric_limits<uint128_t>
|
||||
template <>
|
||||
struct numeric_limits<uint128_t>
|
||||
{
|
||||
static constexpr uint128_t min()
|
||||
{
|
||||
@ -57,6 +64,6 @@ template<> struct numeric_limits<uint128_t>
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace datatypes
|
||||
} // namespace datatypes
|
||||
|
||||
#endif // MCS_NUMERIC_LIMITS_H_INCLUDED
|
||||
#endif // MCS_NUMERIC_LIMITS_H_INCLUDED
|
||||
|
@ -15,39 +15,35 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
|
||||
#ifndef MCS_DATATYPES_STRING_H
|
||||
#define MCS_DATATYPES_STRING_H
|
||||
|
||||
#include "conststring.h"
|
||||
#include "collation.h" // class Charset
|
||||
#include "collation.h" // class Charset
|
||||
|
||||
namespace datatypes
|
||||
{
|
||||
|
||||
class TCharShort
|
||||
{
|
||||
int64_t mValue;
|
||||
public:
|
||||
TCharShort(int64_t value)
|
||||
:mValue(value)
|
||||
{ }
|
||||
utils::ConstString toConstString(uint32_t width) const
|
||||
{
|
||||
utils::ConstString res = utils::ConstString((const char *) &mValue, width);
|
||||
return res.rtrimZero();
|
||||
}
|
||||
static int strnncollsp(const datatypes::Charset &cs, int64_t a, int64_t b, uint32_t width)
|
||||
{
|
||||
datatypes::TCharShort sa(a);
|
||||
datatypes::TCharShort sb(b);
|
||||
return cs.strnncollsp(sa.toConstString(width),
|
||||
sb.toConstString(width));
|
||||
}
|
||||
int64_t mValue;
|
||||
|
||||
public:
|
||||
TCharShort(int64_t value) : mValue(value)
|
||||
{
|
||||
}
|
||||
utils::ConstString toConstString(uint32_t width) const
|
||||
{
|
||||
utils::ConstString res = utils::ConstString((const char*)&mValue, width);
|
||||
return res.rtrimZero();
|
||||
}
|
||||
static int strnncollsp(const datatypes::Charset& cs, int64_t a, int64_t b, uint32_t width)
|
||||
{
|
||||
datatypes::TCharShort sa(a);
|
||||
datatypes::TCharShort sb(b);
|
||||
return cs.strnncollsp(sa.toConstString(width), sb.toConstString(width));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace datatypes
|
||||
|
||||
} // namespace datatypes
|
||||
|
||||
|
||||
#endif // MCS_DATATYPES_STRING_H
|
||||
#endif // MCS_DATATYPES_STRING_H
|
||||
|
@ -15,33 +15,26 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
|
||||
#ifndef NUMERICLITERAL_H
|
||||
#define NUMERICLITERAL_H
|
||||
|
||||
#include "genericparser.h"
|
||||
#include "mcs_datatype.h"
|
||||
|
||||
|
||||
namespace literal
|
||||
{
|
||||
|
||||
using utils::ConstString;
|
||||
using genericparser::Parser;
|
||||
using datatypes::DataCondition;
|
||||
using genericparser::Parser;
|
||||
using utils::ConstString;
|
||||
|
||||
typedef uint32_t scale_t;
|
||||
|
||||
|
||||
|
||||
template<class A>
|
||||
class Converter: public Parser,
|
||||
public A
|
||||
template <class A>
|
||||
class Converter : public Parser, public A
|
||||
{
|
||||
public:
|
||||
Converter(const char *str, size_t length, DataCondition & error)
|
||||
:Parser(str, length),
|
||||
A(&Parser::skipLeadingSpaces())
|
||||
public:
|
||||
Converter(const char* str, size_t length, DataCondition& error)
|
||||
: Parser(str, length), A(&Parser::skipLeadingSpaces())
|
||||
{
|
||||
if (Parser::syntaxError())
|
||||
{
|
||||
@ -57,15 +50,14 @@ public:
|
||||
'1e' - exponent marker was not followed by <exponent>, expect '1e1'
|
||||
'1e+' - in <exponent>, <sign> was not followed by a digit, expect '1e+1'
|
||||
*/
|
||||
error|=(DataCondition::X_INVALID_CHARACTER_VALUE_FOR_CAST);
|
||||
error |= (DataCondition::X_INVALID_CHARACTER_VALUE_FOR_CAST);
|
||||
}
|
||||
}
|
||||
Converter(const std::string & str, DataCondition &error)
|
||||
:Converter(str.data(), str.length(), error)
|
||||
{ }
|
||||
Converter(const std::string& str, DataCondition& error) : Converter(str.data(), str.length(), error)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
SQL Standard definition for <cast specification>
|
||||
@ -144,70 +136,83 @@ Grammar
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Terminal symbols
|
||||
//
|
||||
|
||||
class Period: public ConstString
|
||||
class Period : public ConstString
|
||||
{
|
||||
public:
|
||||
explicit Period(Parser *p)
|
||||
:ConstString(p->tokenChar('.'))
|
||||
{ }
|
||||
bool isNull() const { return mStr == nullptr; }
|
||||
public:
|
||||
explicit Period(Parser* p) : ConstString(p->tokenChar('.'))
|
||||
{
|
||||
}
|
||||
bool isNull() const
|
||||
{
|
||||
return mStr == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ExponentMarker: public ConstString
|
||||
class ExponentMarker : public ConstString
|
||||
{
|
||||
public:
|
||||
explicit ExponentMarker(Parser *p)
|
||||
:ConstString(p->tokenAnyCharOf('e', 'E'))
|
||||
{ }
|
||||
bool isNull() const { return mStr == nullptr; }
|
||||
public:
|
||||
explicit ExponentMarker(Parser* p) : ConstString(p->tokenAnyCharOf('e', 'E'))
|
||||
{
|
||||
}
|
||||
bool isNull() const
|
||||
{
|
||||
return mStr == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Sign: public ConstString
|
||||
class Sign : public ConstString
|
||||
{
|
||||
public:
|
||||
explicit Sign(): ConstString(NULL, 0) { }
|
||||
explicit Sign(const ConstString &str)
|
||||
:ConstString(str)
|
||||
{ }
|
||||
explicit Sign(Parser *p)
|
||||
:ConstString(p->tokenAnyCharOf('+', '-'))
|
||||
{ }
|
||||
static Sign empty(Parser *p)
|
||||
public:
|
||||
explicit Sign() : ConstString(NULL, 0)
|
||||
{
|
||||
}
|
||||
explicit Sign(const ConstString& str) : ConstString(str)
|
||||
{
|
||||
}
|
||||
explicit Sign(Parser* p) : ConstString(p->tokenAnyCharOf('+', '-'))
|
||||
{
|
||||
}
|
||||
static Sign empty(Parser* p)
|
||||
{
|
||||
return Sign(p->tokStartConstString());
|
||||
}
|
||||
bool isNull() const { return mStr == nullptr; }
|
||||
bool negative() const { return eq('-'); }
|
||||
bool isNull() const
|
||||
{
|
||||
return mStr == nullptr;
|
||||
}
|
||||
bool negative() const
|
||||
{
|
||||
return eq('-');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Digits: public ConstString
|
||||
class Digits : public ConstString
|
||||
{
|
||||
public:
|
||||
explicit Digits()
|
||||
:ConstString(NULL, 0)
|
||||
{ }
|
||||
explicit Digits(const char *str, size_t length)
|
||||
:ConstString(str, length)
|
||||
{ }
|
||||
explicit Digits(const ConstString &str)
|
||||
:ConstString(str)
|
||||
{ }
|
||||
explicit Digits(Parser *p)
|
||||
:ConstString(p->tokenDigits())
|
||||
{ }
|
||||
bool isNull() const { return mStr == nullptr; }
|
||||
public:
|
||||
explicit Digits() : ConstString(NULL, 0)
|
||||
{
|
||||
}
|
||||
explicit Digits(const char* str, size_t length) : ConstString(str, length)
|
||||
{
|
||||
}
|
||||
explicit Digits(const ConstString& str) : ConstString(str)
|
||||
{
|
||||
}
|
||||
explicit Digits(Parser* p) : ConstString(p->tokenDigits())
|
||||
{
|
||||
}
|
||||
bool isNull() const
|
||||
{
|
||||
return mStr == nullptr;
|
||||
}
|
||||
|
||||
void skipLeadingZeroDigits()
|
||||
{
|
||||
for ( ; mLength > 0 && mStr[0] == '0'; )
|
||||
for (; mLength > 0 && mStr[0] == '0';)
|
||||
{
|
||||
mStr++;
|
||||
mLength--;
|
||||
@ -215,33 +220,32 @@ public:
|
||||
}
|
||||
void skipTrailingZeroDigits()
|
||||
{
|
||||
for ( ; mLength > 0 && mStr[mLength - 1] == '0' ; )
|
||||
for (; mLength > 0 && mStr[mLength - 1] == '0';)
|
||||
mLength--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Non-terminal symbols
|
||||
//
|
||||
|
||||
// <unsigned integer> ::= <digit> ...
|
||||
class UnsignedInteger: public Digits
|
||||
class UnsignedInteger : public Digits
|
||||
{
|
||||
public:
|
||||
explicit UnsignedInteger()
|
||||
:Digits()
|
||||
{ }
|
||||
explicit UnsignedInteger(const char *str, size_t length)
|
||||
:Digits(str, length)
|
||||
{ }
|
||||
explicit UnsignedInteger(const ConstString &str)
|
||||
:Digits(str)
|
||||
{ }
|
||||
explicit UnsignedInteger(Parser *p)
|
||||
:Digits(p)
|
||||
{ }
|
||||
static UnsignedInteger empty(const Parser *p)
|
||||
public:
|
||||
explicit UnsignedInteger() : Digits()
|
||||
{
|
||||
}
|
||||
explicit UnsignedInteger(const char* str, size_t length) : Digits(str, length)
|
||||
{
|
||||
}
|
||||
explicit UnsignedInteger(const ConstString& str) : Digits(str)
|
||||
{
|
||||
}
|
||||
explicit UnsignedInteger(Parser* p) : Digits(p)
|
||||
{
|
||||
}
|
||||
static UnsignedInteger empty(const Parser* p)
|
||||
{
|
||||
return UnsignedInteger(p->tokStartConstString());
|
||||
}
|
||||
@ -250,182 +254,177 @@ public:
|
||||
return UnsignedInteger(str(), length() > len ? len : length());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toXIntPositiveContinue(T start, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveContinue(T start, DataCondition& error) const
|
||||
{
|
||||
const char *e = end();
|
||||
const char* e = end();
|
||||
T val = start;
|
||||
for (const char *s= mStr; s < e; s++)
|
||||
for (const char* s = mStr; s < e; s++)
|
||||
{
|
||||
constexpr T cutoff = datatypes::numeric_limits<T>::max() / 10;
|
||||
if (val > cutoff)
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return datatypes::numeric_limits<T>::max();
|
||||
}
|
||||
val*= 10;
|
||||
val *= 10;
|
||||
T newval = val + (s[0] - '0');
|
||||
if (newval < val)
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return datatypes::numeric_limits<T>::max();
|
||||
}
|
||||
val = newval;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
template<typename T>
|
||||
T toXIntPositive(DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositive(DataCondition& error) const
|
||||
{
|
||||
return toXIntPositiveContinue<T>(0, error);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toSIntNegativeContinue(T start, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toSIntNegativeContinue(T start, DataCondition& error) const
|
||||
{
|
||||
const char *e = end();
|
||||
const char* e = end();
|
||||
T val = start;
|
||||
for (const char *s= mStr; s < e; s++)
|
||||
for (const char* s = mStr; s < e; s++)
|
||||
{
|
||||
constexpr T cutoff = datatypes::numeric_limits<T>::min() / 10;
|
||||
if (val < cutoff)
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return datatypes::numeric_limits<T>::min();
|
||||
}
|
||||
val*= 10;
|
||||
val *= 10;
|
||||
T newval = val - (s[0] - '0');
|
||||
if (newval > val)
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return datatypes::numeric_limits<T>::min();
|
||||
}
|
||||
val = newval;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
template<typename T>
|
||||
T toSIntNegative(DataCondition & error) const
|
||||
template <typename T>
|
||||
T toSIntNegative(DataCondition& error) const
|
||||
{
|
||||
return toSIntNegativeContinue<T>(0, error);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toXIntPositiveRoundAwayFromZeroContinue(T start, bool round, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveRoundAwayFromZeroContinue(T start, bool round, DataCondition& error) const
|
||||
{
|
||||
T val = toXIntPositiveContinue<T>(start, error);
|
||||
if (val == datatypes::numeric_limits<T>::max() && round)
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return val;
|
||||
}
|
||||
return val + round;
|
||||
}
|
||||
template<typename T>
|
||||
T toXIntPositiveRoundAwayFromZero(bool round, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveRoundAwayFromZero(bool round, DataCondition& error) const
|
||||
{
|
||||
return toXIntPositiveRoundAwayFromZeroContinue<T>(0, round, error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// <signed integer> := [<sign>] <unsigned integer>
|
||||
class SignedInteger: public Parser::DD2OM<Sign,UnsignedInteger>
|
||||
class SignedInteger : public Parser::DD2OM<Sign, UnsignedInteger>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using DD2OM::DD2OM;
|
||||
bool isNull() const { return UnsignedInteger::isNull(); }
|
||||
bool isNull() const
|
||||
{
|
||||
return UnsignedInteger::isNull();
|
||||
}
|
||||
|
||||
template<typename T> T abs(DataCondition & error) const
|
||||
template <typename T>
|
||||
T abs(DataCondition& error) const
|
||||
{
|
||||
return toXIntPositive<T>(error);
|
||||
}
|
||||
|
||||
template<typename T> T toSInt(DataCondition & error) const
|
||||
template <typename T>
|
||||
T toSInt(DataCondition& error) const
|
||||
{
|
||||
return negative() ?
|
||||
toSIntNegative<T>(error) :
|
||||
toXIntPositive<T>(error);
|
||||
return negative() ? toSIntNegative<T>(error) : toXIntPositive<T>(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// E <signed integer>
|
||||
class EExponent: public Parser::UD2MM<ExponentMarker, SignedInteger>
|
||||
class EExponent : public Parser::UD2MM<ExponentMarker, SignedInteger>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using UD2MM::UD2MM;
|
||||
};
|
||||
|
||||
|
||||
// <period> <unsigned integer>
|
||||
class ExactUnsignedNumericLiteralFractionAlone: public Parser::UD2MM<Period, UnsignedInteger>
|
||||
class ExactUnsignedNumericLiteralFractionAlone : public Parser::UD2MM<Period, UnsignedInteger>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using UD2MM::UD2MM;
|
||||
};
|
||||
|
||||
|
||||
// <period> [ <unsigned integer> ]
|
||||
class PeriodOptUnsignedInteger: public Parser::UD2MO<Period, UnsignedInteger>
|
||||
class PeriodOptUnsignedInteger : public Parser::UD2MO<Period, UnsignedInteger>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using UD2MO::UD2MO;
|
||||
static PeriodOptUnsignedInteger empty(Parser *p)
|
||||
static PeriodOptUnsignedInteger empty(Parser* p)
|
||||
{
|
||||
return PeriodOptUnsignedInteger(UnsignedInteger(p->tokStartConstString()));
|
||||
}
|
||||
const PeriodOptUnsignedInteger & fraction() const
|
||||
const PeriodOptUnsignedInteger& fraction() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// <integral unsigned integer> := <unsigned integer>
|
||||
class IntegralUnsignedInteger: public UnsignedInteger
|
||||
class IntegralUnsignedInteger : public UnsignedInteger
|
||||
{
|
||||
public:
|
||||
explicit IntegralUnsignedInteger(Parser *p)
|
||||
:UnsignedInteger(p)
|
||||
{ }
|
||||
const UnsignedInteger & integral() const
|
||||
public:
|
||||
explicit IntegralUnsignedInteger(Parser* p) : UnsignedInteger(p)
|
||||
{
|
||||
}
|
||||
const UnsignedInteger& integral() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// <integral unsigned integer> [ <period> [ <unsigned integer> ] ]
|
||||
|
||||
class ExactUnsignedNumericLiteralIntegralOptFraction:
|
||||
public Parser::DD2MO<IntegralUnsignedInteger,
|
||||
PeriodOptUnsignedInteger>
|
||||
class ExactUnsignedNumericLiteralIntegralOptFraction
|
||||
: public Parser::DD2MO<IntegralUnsignedInteger, PeriodOptUnsignedInteger>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using DD2MO::DD2MO;
|
||||
};
|
||||
|
||||
|
||||
// A container for integral and fractional parts
|
||||
class UnsignedIntegerDecimal
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
UnsignedInteger mIntegral;
|
||||
UnsignedInteger mFraction;
|
||||
public:
|
||||
explicit UnsignedIntegerDecimal(const UnsignedInteger &intg,
|
||||
const UnsignedInteger &frac)
|
||||
:mIntegral(intg),
|
||||
mFraction(frac)
|
||||
{ }
|
||||
explicit UnsignedIntegerDecimal(const ExactUnsignedNumericLiteralFractionAlone &rhs)
|
||||
:mFraction(rhs)
|
||||
{ }
|
||||
explicit UnsignedIntegerDecimal(const ExactUnsignedNumericLiteralIntegralOptFraction &rhs)
|
||||
:mIntegral(rhs.integral()),
|
||||
mFraction(rhs.fraction())
|
||||
{ }
|
||||
|
||||
public:
|
||||
explicit UnsignedIntegerDecimal(const UnsignedInteger& intg, const UnsignedInteger& frac)
|
||||
: mIntegral(intg), mFraction(frac)
|
||||
{
|
||||
}
|
||||
explicit UnsignedIntegerDecimal(const ExactUnsignedNumericLiteralFractionAlone& rhs) : mFraction(rhs)
|
||||
{
|
||||
}
|
||||
explicit UnsignedIntegerDecimal(const ExactUnsignedNumericLiteralIntegralOptFraction& rhs)
|
||||
: mIntegral(rhs.integral()), mFraction(rhs.fraction())
|
||||
{
|
||||
}
|
||||
|
||||
size_t IntFracDigits() const
|
||||
{
|
||||
@ -443,51 +442,55 @@ public:
|
||||
mFraction.skipTrailingZeroDigits();
|
||||
}
|
||||
|
||||
template<typename T> T toXIntPositive(DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositive(DataCondition& error) const
|
||||
{
|
||||
T val = mIntegral.toXIntPositive<T>(error);
|
||||
return mFraction.toXIntPositiveContinue<T>(val, error);
|
||||
}
|
||||
|
||||
template<typename T> T toXIntPositiveRoundAwayFromZero(bool roundUp, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveRoundAwayFromZero(bool roundUp, DataCondition& error) const
|
||||
{
|
||||
T val = mIntegral.toXIntPositive<T>(error);
|
||||
return mFraction.toXIntPositiveRoundAwayFromZeroContinue<T>(val, roundUp, error);
|
||||
}
|
||||
|
||||
template<typename T> T toXIntPositiveScaleUp(size_t scale, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveScaleUp(size_t scale, DataCondition& error) const
|
||||
{
|
||||
T val = toXIntPositive<T>(error);
|
||||
if (val == datatypes::numeric_limits<T>::max())
|
||||
return val;
|
||||
for ( ; scale ; scale--)
|
||||
for (; scale; scale--)
|
||||
{
|
||||
constexpr T cutoff = datatypes::numeric_limits<T>::max() / 10;
|
||||
if (val > cutoff)
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return datatypes::numeric_limits<T>::max();
|
||||
}
|
||||
val*= 10;
|
||||
val *= 10;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
template<typename T> T toXIntPositiveRound(DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveRound(DataCondition& error) const
|
||||
{
|
||||
bool roundUp = mFraction.length() && mFraction.str()[0] >= '5';
|
||||
return mIntegral.toXIntPositiveRoundAwayFromZero<T>(roundUp, error);
|
||||
}
|
||||
|
||||
template<typename T> T toXIntPositiveRoundExp(uint64_t absExp, bool negExp,
|
||||
DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveRoundExp(uint64_t absExp, bool negExp, DataCondition& error) const
|
||||
{
|
||||
if (absExp == 0)
|
||||
return toXIntPositiveRound<T>(error);
|
||||
|
||||
if (negExp)
|
||||
{
|
||||
if (mIntegral.length() == absExp) // 567.8e-3 -> 0.5678 -> 1
|
||||
if (mIntegral.length() == absExp) // 567.8e-3 -> 0.5678 -> 1
|
||||
return mIntegral.str()[0] >= '5' ? 1 : 0;
|
||||
if (mIntegral.length() < absExp) // 123e-4 -> 0.0123
|
||||
return 0;
|
||||
@ -499,7 +502,7 @@ public:
|
||||
}
|
||||
|
||||
// Positive exponent: 123.456e2
|
||||
if (mFraction.length() >= absExp) // 123.456e2 -> 12345.6 -> 12346
|
||||
if (mFraction.length() >= absExp) // 123.456e2 -> 12345.6 -> 12346
|
||||
{
|
||||
bool roundUp = mFraction.length() > absExp && mFraction.str()[absExp] >= '5';
|
||||
UnsignedIntegerDecimal tmp(mIntegral, mFraction.left(absExp));
|
||||
@ -510,42 +513,38 @@ public:
|
||||
size_t diff = absExp - mFraction.length();
|
||||
return toXIntPositiveScaleUp<T>(diff, error);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// <exact unsigned numeric literal> :=
|
||||
// <period> [ <unsigned integer> ]
|
||||
// | <unsigned integer> [ <period> [ <unsigned integer> ] ]
|
||||
|
||||
class ExactUnsignedNumericLiteral:
|
||||
public Parser::Choice2<UnsignedIntegerDecimal,
|
||||
ExactUnsignedNumericLiteralFractionAlone,
|
||||
ExactUnsignedNumericLiteralIntegralOptFraction>
|
||||
class ExactUnsignedNumericLiteral
|
||||
: public Parser::Choice2<UnsignedIntegerDecimal, ExactUnsignedNumericLiteralFractionAlone,
|
||||
ExactUnsignedNumericLiteralIntegralOptFraction>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using Choice2::Choice2;
|
||||
};
|
||||
|
||||
|
||||
// <unsigned numeric literal> ::= <exact numeric literal> [ E <exponent> ]
|
||||
|
||||
class UnsignedNumericLiteral: public Parser::DM2MO<ExactUnsignedNumericLiteral,EExponent>
|
||||
class UnsignedNumericLiteral : public Parser::DM2MO<ExactUnsignedNumericLiteral, EExponent>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using DM2MO::DM2MO;
|
||||
void normalize()
|
||||
{
|
||||
ExactUnsignedNumericLiteral::normalize();
|
||||
mB.skipLeadingZeroDigits();
|
||||
}
|
||||
const SignedInteger & exponent() const
|
||||
const SignedInteger& exponent() const
|
||||
{
|
||||
return mB;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toXIntPositiveRound(DataCondition & error) const
|
||||
template <typename T>
|
||||
T toXIntPositiveRound(DataCondition& error) const
|
||||
{
|
||||
size_t availableDigits = IntFracDigits();
|
||||
if (!availableDigits)
|
||||
@ -554,35 +553,36 @@ public:
|
||||
return ExactUnsignedNumericLiteral::toXIntPositiveRoundExp<T>(absexp, exponent().negative(), error);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toPackedDecimalPositive(scale_t scale, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toPackedDecimalPositive(scale_t scale, DataCondition& error) const
|
||||
{
|
||||
size_t availableDigits = IntFracDigits();
|
||||
if (!availableDigits)
|
||||
return 0;
|
||||
int64_t exp = exponent().toSInt<int64_t>(error);
|
||||
if (exp <= datatypes::numeric_limits<int64_t>::max() - scale)
|
||||
exp+= scale;
|
||||
exp += scale;
|
||||
if (exp < 0)
|
||||
{
|
||||
if (exp == datatypes::numeric_limits<int64_t>::min())
|
||||
exp++; // Avoid undefined behaviour in the unary minus below:
|
||||
return ExactUnsignedNumericLiteral::toXIntPositiveRoundExp<T>((uint64_t) -exp, true, error);
|
||||
exp++; // Avoid undefined behaviour in the unary minus below:
|
||||
return ExactUnsignedNumericLiteral::toXIntPositiveRoundExp<T>((uint64_t)-exp, true, error);
|
||||
}
|
||||
return ExactUnsignedNumericLiteral::toXIntPositiveRoundExp<T>((uint64_t) exp, false, error);
|
||||
return ExactUnsignedNumericLiteral::toXIntPositiveRoundExp<T>((uint64_t)exp, false, error);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// <signed numeric literal> ::= [ <sign> ] <unsigned numeric literal>
|
||||
class SignedNumericLiteral: public Parser::DD2OM<Sign,UnsignedNumericLiteral>
|
||||
class SignedNumericLiteral : public Parser::DD2OM<Sign, UnsignedNumericLiteral>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using DD2OM::DD2OM;
|
||||
bool isNull() const { return UnsignedNumericLiteral::isNull(); }
|
||||
bool isNull() const
|
||||
{
|
||||
return UnsignedNumericLiteral::isNull();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
T toUIntXRound() const
|
||||
{
|
||||
if (negative())
|
||||
@ -590,31 +590,30 @@ public:
|
||||
return UnsignedNumericLiteral::toXIntPositiveRound<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toPackedUDecimal(scale_t scale, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toPackedUDecimal(scale_t scale, DataCondition& error) const
|
||||
{
|
||||
if (negative())
|
||||
return 0;
|
||||
return UnsignedNumericLiteral::toPackedDecimalPositive<T>(scale, error);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T toPackedSDecimal(scale_t scale, DataCondition & error) const
|
||||
template <typename T>
|
||||
T toPackedSDecimal(scale_t scale, DataCondition& error) const
|
||||
{
|
||||
if (!negative())
|
||||
return UnsignedNumericLiteral::toPackedDecimalPositive<T>(scale, error);
|
||||
typedef typename datatypes::make_unsigned<T>::type UT;
|
||||
UT absval = UnsignedNumericLiteral::toPackedDecimalPositive<UT>(scale, error);
|
||||
if (absval >= (UT) datatypes::numeric_limits<T>::min())
|
||||
if (absval >= (UT)datatypes::numeric_limits<T>::min())
|
||||
{
|
||||
error|= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
error |= DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE;
|
||||
return datatypes::numeric_limits<T>::min();
|
||||
}
|
||||
return - (T) absval;
|
||||
return -(T)absval;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace literal
|
||||
|
||||
} // namespace literal
|
||||
|
||||
#endif // NUMERICLITERAL_H
|
||||
#endif // NUMERICLITERAL_H
|
||||
|
Reference in New Issue
Block a user