ClickHouse/dbms/src/Core/Types.h

198 lines
6.4 KiB
C++
Raw Normal View History

2011-08-28 00:31:30 +00:00
#pragma once
2010-03-01 16:59:51 +00:00
#include <string>
#include <vector>
2018-07-20 19:05:07 +00:00
#include <cstdint>
2010-03-01 16:59:51 +00:00
namespace DB
{
/// Data types for representing elementary values from a database in RAM.
2010-03-01 16:59:51 +00:00
struct Null {};
2010-03-01 16:59:51 +00:00
2018-07-20 19:05:07 +00:00
using UInt8 = uint8_t;
using UInt16 = uint16_t;
using UInt32 = uint32_t;
using UInt64 = uint64_t;
2010-03-01 16:59:51 +00:00
2018-07-20 19:05:07 +00:00
using Int8 = int8_t;
using Int16 = int16_t;
using Int32 = int32_t;
using Int64 = int64_t;
2010-03-01 16:59:51 +00:00
using Float32 = float;
using Float64 = double;
2010-03-01 16:59:51 +00:00
using String = std::string;
2011-08-28 00:31:30 +00:00
/** Note that for types not used in DB, IsNumber is false.
*/
template <typename T> constexpr bool IsNumber = false;
template <> constexpr bool IsNumber<UInt8> = true;
template <> constexpr bool IsNumber<UInt16> = true;
template <> constexpr bool IsNumber<UInt32> = true;
template <> constexpr bool IsNumber<UInt64> = true;
template <> constexpr bool IsNumber<Int8> = true;
template <> constexpr bool IsNumber<Int16> = true;
template <> constexpr bool IsNumber<Int32> = true;
template <> constexpr bool IsNumber<Int64> = true;
template <> constexpr bool IsNumber<Float32> = true;
template <> constexpr bool IsNumber<Float64> = true;
2011-08-28 00:31:30 +00:00
template <typename T> struct TypeName;
template <> struct TypeName<UInt8> { static const char * get() { return "UInt8"; } };
template <> struct TypeName<UInt16> { static const char * get() { return "UInt16"; } };
template <> struct TypeName<UInt32> { static const char * get() { return "UInt32"; } };
template <> struct TypeName<UInt64> { static const char * get() { return "UInt64"; } };
template <> struct TypeName<Int8> { static const char * get() { return "Int8"; } };
template <> struct TypeName<Int16> { static const char * get() { return "Int16"; } };
template <> struct TypeName<Int32> { static const char * get() { return "Int32"; } };
template <> struct TypeName<Int64> { static const char * get() { return "Int64"; } };
template <> struct TypeName<Float32> { static const char * get() { return "Float32"; } };
template <> struct TypeName<Float64> { static const char * get() { return "Float64"; } };
template <> struct TypeName<String> { static const char * get() { return "String"; } };
enum class TypeIndex
{
None = 0,
UInt8,
UInt16,
UInt32,
UInt64,
UInt128,
Int8,
Int16,
Int32,
Int64,
Int128,
Float32,
Float64,
Date,
DateTime,
String,
FixedString,
Enum8,
Enum16,
2018-08-21 18:55:36 +00:00
Decimal32,
Decimal64,
Decimal128,
UUID,
2018-08-31 08:59:21 +00:00
Array,
Tuple,
};
template <typename T> struct TypeId;
template <> struct TypeId<UInt8> { static constexpr const TypeIndex value = TypeIndex::UInt8; };
template <> struct TypeId<UInt16> { static constexpr const TypeIndex value = TypeIndex::UInt16; };
template <> struct TypeId<UInt32> { static constexpr const TypeIndex value = TypeIndex::UInt32; };
template <> struct TypeId<UInt64> { static constexpr const TypeIndex value = TypeIndex::UInt64; };
template <> struct TypeId<Int8> { static constexpr const TypeIndex value = TypeIndex::Int8; };
template <> struct TypeId<Int16> { static constexpr const TypeIndex value = TypeIndex::Int16; };
template <> struct TypeId<Int32> { static constexpr const TypeIndex value = TypeIndex::Int32; };
template <> struct TypeId<Int64> { static constexpr const TypeIndex value = TypeIndex::Int64; };
template <> struct TypeId<Float32> { static constexpr const TypeIndex value = TypeIndex::Float32; };
template <> struct TypeId<Float64> { static constexpr const TypeIndex value = TypeIndex::Float64; };
/// Not a data type in database, defined just for convenience.
using Strings = std::vector<String>;
2011-08-28 00:31:30 +00:00
}
2018-07-25 19:38:21 +00:00
#if 1 /// __int128
namespace DB
{
using Int128 = __int128;
template <> constexpr bool IsNumber<Int128> = true;
template <> struct TypeName<Int128> { static const char * get() { return "Int128"; } };
template <> struct TypeId<Int128> { static constexpr const TypeIndex value = TypeIndex::Int128; };
2018-07-25 19:38:21 +00:00
}
namespace std
{
template <> struct is_signed<__int128>
{
static constexpr bool value = true;
};
template <> struct is_unsigned<__int128>
{
static constexpr bool value = false;
};
template <> struct is_integral<__int128>
{
static constexpr bool value = true;
};
template <> struct is_arithmetic<__int128>
{
static constexpr bool value = true;
};
}
#endif
2018-08-07 13:57:28 +00:00
namespace DB
{
2018-08-21 04:31:35 +00:00
/// Own FieldType for Decimal.
/// It is only a "storage" for decimal. To perform operations, you also have to provide a scale (number of digits after point).
2018-08-07 13:57:28 +00:00
template <typename T>
2018-08-21 04:31:35 +00:00
struct Decimal
2018-08-07 13:57:28 +00:00
{
using NativeType = T;
2018-08-21 04:31:35 +00:00
Decimal() = default;
Decimal(Decimal<T> &&) = default;
Decimal(const Decimal<T> &) = default;
2018-08-07 13:57:28 +00:00
2018-08-21 04:31:35 +00:00
Decimal(const T & value_)
2018-08-07 13:57:28 +00:00
: value(value_)
{}
template <typename U>
2018-08-21 04:31:35 +00:00
Decimal(const Decimal<U> & x)
2018-08-07 13:57:28 +00:00
: value(x)
{}
2018-08-21 04:31:35 +00:00
constexpr Decimal<T> & operator = (Decimal<T> &&) = default;
constexpr Decimal<T> & operator = (const Decimal<T> &) = default;
2018-08-07 13:57:28 +00:00
operator T () const { return value; }
2018-08-21 04:31:35 +00:00
const Decimal<T> & operator += (const T & x) { value += x; return *this; }
const Decimal<T> & operator -= (const T & x) { value -= x; return *this; }
const Decimal<T> & operator *= (const T & x) { value *= x; return *this; }
const Decimal<T> & operator /= (const T & x) { value /= x; return *this; }
const Decimal<T> & operator %= (const T & x) { value %= x; return *this; }
2018-08-07 13:57:28 +00:00
T value;
};
2018-08-21 04:31:35 +00:00
using Decimal32 = Decimal<Int32>;
using Decimal64 = Decimal<Int64>;
using Decimal128 = Decimal<Int128>;
2018-08-07 13:57:28 +00:00
2018-08-21 04:31:35 +00:00
template <> struct TypeName<Decimal32> { static const char * get() { return "Decimal32"; } };
template <> struct TypeName<Decimal64> { static const char * get() { return "Decimal64"; } };
template <> struct TypeName<Decimal128> { static const char * get() { return "Decimal128"; } };
2018-08-07 13:57:28 +00:00
2018-08-21 18:55:36 +00:00
template <> struct TypeId<Decimal32> { static constexpr const TypeIndex value = TypeIndex::Decimal32; };
template <> struct TypeId<Decimal64> { static constexpr const TypeIndex value = TypeIndex::Decimal64; };
template <> struct TypeId<Decimal128> { static constexpr const TypeIndex value = TypeIndex::Decimal128; };
2018-08-08 10:36:03 +00:00
template <typename T>
2018-08-21 04:31:35 +00:00
constexpr bool IsDecimalNumber = false;
template <> constexpr bool IsDecimalNumber<Decimal32> = true;
template <> constexpr bool IsDecimalNumber<Decimal64> = true;
template <> constexpr bool IsDecimalNumber<Decimal128> = true;
2018-08-07 13:57:28 +00:00
}