1
0
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:
Leonid Fedorov
2022-02-11 12:24:40 +00:00
parent 509f005be7
commit 7c808317dc
1367 changed files with 394342 additions and 413129 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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