74 enum class Type :
unsigned short {
93 Value() noexcept : m_value(
std::monostate{}), m_type(Type::Null) {}
99 Value(
int value) noexcept : m_value(value), m_type(Type::Integer) {}
105 Value(
unsigned int value) noexcept : m_value(value), m_type(Type::UnsignedInteger) {}
111 Value(
long int value) noexcept : m_value(
static_cast<long long int>(value)), m_type(Type::LongInteger) {}
117 Value(
unsigned long int value) noexcept : m_value(
static_cast<unsigned long long int>(value)), m_type(Type::UnsignedLongInteger) {}
123 Value(
long long int value) noexcept : m_value(value), m_type(Type::LongInteger) {}
129 Value(
unsigned long long int value) noexcept : m_value(value), m_type(Type::UnsignedLongInteger) {}
135 Value(
double value) noexcept : m_value(value), m_type(Type::Double) {}
141 Value(std::string_view value)
noexcept;
159 template <
typename T>
161 Value(T &&value) noexcept : m_value(value), m_type(Type::Boolean) {}
190 return m_value == other.m_value;
199 return !(*
this == other);
213 template <typename T>
215 std::decay_t<T> Get()
const {
216 using To = std::decay_t<T>;
217 return std::visit([](
auto &&val) -> To {
218 using From = std::decay_t<
decltype(val)>;
220 throw WrongValueType(
"Requested type does not match stored type (null).");
224 return convert_numeric<To, From>(val);
226 throw WrongValueType(
"Requested type does not match stored type.");
245 return m_type == Type::Null;
257 template <
typename To,
typename From>
259 static To convert_numeric(
const From &val) {
262 std::intmax_t from =
static_cast<std::intmax_t
>(val);
264 if (from <
static_cast<std::intmax_t
>(std::numeric_limits<To>::lowest()) || from >
static_cast<std::intmax_t
>(std::numeric_limits<To>::max()))
265 throw WrongValueType(
"Integer conversion would overflow/narrow.");
266 return static_cast<To
>(from);
269 throw WrongValueType(
"Negative value cannot be converted to unsigned.");
270 if (
static_cast<std::uintmax_t
>(from) >
static_cast<std::uintmax_t
>(std::numeric_limits<To>::max()))
271 throw WrongValueType(
"Integer conversion would overflow/narrow.");
272 return static_cast<To
>(from);
275 std::uintmax_t from =
static_cast<std::uintmax_t
>(val);
277 if (from >
static_cast<std::uintmax_t
>(std::numeric_limits<To>::max()))
278 throw WrongValueType(
"Integer conversion would overflow/narrow.");
279 return static_cast<To
>(from);
281 if (from >
static_cast<std::uintmax_t
>(std::numeric_limits<To>::max()))
282 throw WrongValueType(
"Integer conversion would overflow/narrow.");
283 return static_cast<To
>(from);
287 return static_cast<To
>(val);
289 long double d =
static_cast<long double>(val);
290 if (!std::isfinite(d))
291 throw WrongValueType(
"Non-finite floating conversion to integer.");
292 if (std::trunc(d) != d)
293 throw WrongValueType(
"Floating value has fractional part; would lose data.");
294 const long double upper_bound = std::ldexp(1.0L, std::numeric_limits<To>::digits);
296 if (d < -upper_bound || d >= upper_bound)
297 throw WrongValueType(
"Floating to integer conversion would overflow/narrow.");
300 throw WrongValueType(
"Negative value cannot be converted to unsigned.");
301 if (d >= upper_bound)
302 throw WrongValueType(
"Floating to integer conversion would overflow/narrow.");
304 return static_cast<To
>(d);
306 return static_cast<To
>(val);
308 throw WrongValueType(
"Unsupported numeric conversion.");
Type-erased SQL value (NULL, integers, double, text, blob, bool).
Definition value.hxx:68
Value(Value &&other) noexcept
Move constructor.
bool IsNull() const noexcept
Whether the value is SQL NULL.
Definition value.hxx:244
Value(long int value) noexcept
From a signed long int, stored as long long int.
Definition value.hxx:111
Value(int value) noexcept
From a signed int.
Definition value.hxx:99
bool operator==(const Value &other) const noexcept
Equality of the stored alternatives.
Definition value.hxx:189
Value(unsigned long int value) noexcept
From an unsigned long int, stored as unsigned long long int.
Definition value.hxx:117
Value(StormByte::BinaryData &&value) noexcept
Move a blob into this value.
Value(unsigned int value) noexcept
From an unsigned int.
Definition value.hxx:105
Value(std::string_view value) noexcept
Copy UTF-8 text into a String-owned value.
Value(double value) noexcept
From a double.
Definition value.hxx:135
Type
Discriminator for the stored alternative.
Definition value.hxx:74
Value(unsigned long long int value) noexcept
From an unsigned long long int.
Definition value.hxx:129
Value(T &&value) noexcept
From a bool.
Definition value.hxx:161
Value(const Value &other)
Copy constructor.
Type Type() const noexcept
Discriminator of the stored alternative.
Definition value.hxx:236
virtual ~Value() noexcept
Destructor.
Value & operator=(Value &&other) noexcept
Move assignment.
Value & operator=(const Value &other)
Copy assignment.
Value() noexcept
Default constructor.
Definition value.hxx:93
bool operator!=(const Value &other) const noexcept
Inequality.
Definition value.hxx:198
Value(const StormByte::BinaryData &value)
Copy a blob into Base-owned storage.
Value(long long int value) noexcept
From a signed long long int.
Definition value.hxx:123
Value accessed as the wrong type.
Definition exception.hxx:123
std::variant< std::monostate, int, unsigned int, long long int, unsigned long long int, double, StormByte::String::String, bool, StormByte::BinaryData > ValuesVariant
Column alternatives.
Definition typedefs.hxx:76
Root namespace of the StormByte C++ suite.
#define STORMBYTE_DATABASE_PUBLIC
Definition visibility.h:54