mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-14 12:52:17 +00:00
field_view now handles field references
This commit is contained in:
86
include/boost/mysql/detail/auxiliar/field_impl.hpp
Normal file
86
include/boost/mysql/detail/auxiliar/field_impl.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// Copyright (c) 2019-2022 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUXILIAR_FIELD_IMPL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_FIELD_IMPL_HPP
|
||||
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/bad_field_access.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/mp11.hpp>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
// Breaks a circular dependency between field_view and field
|
||||
struct field_impl
|
||||
{
|
||||
using null_t = boost::variant2::monostate;
|
||||
|
||||
using variant_type = boost::variant2::variant<
|
||||
null_t, // Any of the below when the value is NULL
|
||||
std::int64_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
|
||||
std::uint64_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, YEAR, BIT
|
||||
std::string, // CHAR, VARCHAR, BINARY, VARBINARY, TEXT (all sizes), BLOB (all sizes), ENUM, SET, DECIMAL, GEOMTRY
|
||||
float, // FLOAT
|
||||
double, // DOUBLE
|
||||
date, // DATE
|
||||
datetime, // DATETIME, TIMESTAMP
|
||||
time // TIME
|
||||
>;
|
||||
|
||||
variant_type data;
|
||||
|
||||
field_impl() = default;
|
||||
|
||||
template <typename Arg>
|
||||
field_impl(Arg&& arg) noexcept(std::is_nothrow_constructible<variant_type, Arg>::value) : data (std::forward<Arg>(arg)) {}
|
||||
|
||||
field_kind kind() const noexcept { return static_cast<field_kind>(data.index()); }
|
||||
|
||||
template <typename T>
|
||||
const T& as() const
|
||||
{
|
||||
const T* res = boost::variant2::get_if<T>(&data);
|
||||
if (!res)
|
||||
throw bad_field_access();
|
||||
return *res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& as()
|
||||
{
|
||||
T* res = boost::variant2::get_if<T>(&data);
|
||||
if (!res)
|
||||
throw bad_field_access();
|
||||
return *res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& get() const noexcept
|
||||
{
|
||||
constexpr auto I = mp11::mp_find<variant_type, T>::value;
|
||||
return boost::variant2::unsafe_get<I>(data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& get() noexcept
|
||||
{
|
||||
constexpr auto I = mp11::mp_find<variant_type, T>::value;
|
||||
return boost::variant2::unsafe_get<I>(data);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -29,10 +29,6 @@ public:
|
||||
offset_(offset), size_(size) {}
|
||||
constexpr std::size_t offset() const noexcept { return offset_; }
|
||||
constexpr std::size_t size() const noexcept { return size_; }
|
||||
constexpr boost::string_view to_string_view(const char* base) const noexcept
|
||||
{
|
||||
return boost::string_view(base + offset_, size_);
|
||||
}
|
||||
constexpr bool operator==(string_view_offset rhs) const noexcept
|
||||
{
|
||||
return offset_ == rhs.offset_ && size_ == rhs.size_;
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#ifndef BOOST_MYSQL_FIELD_HPP
|
||||
#define BOOST_MYSQL_FIELD_HPP
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/field_impl.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
@@ -32,7 +33,7 @@ public:
|
||||
field& operator=(field&&) = default;
|
||||
~field() = default;
|
||||
|
||||
explicit field(std::nullptr_t) noexcept : repr_(null_t()) {}
|
||||
explicit field(std::nullptr_t) noexcept {}
|
||||
field(signed char v) noexcept : repr_(std::int64_t(v)) {}
|
||||
field(short v) noexcept : repr_(std::int64_t(v)) {}
|
||||
field(int v) noexcept : repr_(std::int64_t(v)) {}
|
||||
@@ -51,26 +52,26 @@ public:
|
||||
field(const time& v) noexcept : repr_(v) {}
|
||||
field(const field_view& v) { from_view(v); }
|
||||
|
||||
field& operator=(std::nullptr_t) noexcept { repr_.emplace<null_t>(null_t()); return *this; }
|
||||
field& operator=(signed char v) noexcept { repr_.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(short v) noexcept { repr_.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(int v) noexcept { repr_.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(long v) noexcept { repr_.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(long long v) noexcept { repr_.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(unsigned char v) noexcept { repr_.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned short v) noexcept { repr_.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned int v) noexcept { repr_.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned long v) noexcept { repr_.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned long long v) noexcept { repr_.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(std::string v) { repr_.emplace<std::string>(std::move(v)); return *this; }
|
||||
field& operator=(float v) noexcept { repr_.emplace<float>(v); return *this; }
|
||||
field& operator=(double v) noexcept { repr_.emplace<double>(v); return *this; }
|
||||
field& operator=(const date& v) noexcept { repr_.emplace<date>(v); return *this; }
|
||||
field& operator=(const datetime& v) noexcept { repr_.emplace<datetime>(v); return *this; }
|
||||
field& operator=(const time& v) noexcept { repr_.emplace<time>(v); return *this; }
|
||||
field& operator=(std::nullptr_t) noexcept { repr_.data.emplace<detail::field_impl::null_t>(); return *this; }
|
||||
field& operator=(signed char v) noexcept { repr_.data.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(short v) noexcept { repr_.data.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(int v) noexcept { repr_.data.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(long v) noexcept { repr_.data.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(long long v) noexcept { repr_.data.emplace<std::int64_t>(v); return *this; }
|
||||
field& operator=(unsigned char v) noexcept { repr_.data.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned short v) noexcept { repr_.data.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned int v) noexcept { repr_.data.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned long v) noexcept { repr_.data.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(unsigned long long v) noexcept { repr_.data.emplace<std::uint64_t>(v); return *this; }
|
||||
field& operator=(std::string v) { repr_.data.emplace<std::string>(std::move(v)); return *this; }
|
||||
field& operator=(float v) noexcept { repr_.data.emplace<float>(v); return *this; }
|
||||
field& operator=(double v) noexcept { repr_.data.emplace<double>(v); return *this; }
|
||||
field& operator=(const date& v) noexcept { repr_.data.emplace<date>(v); return *this; }
|
||||
field& operator=(const datetime& v) noexcept { repr_.data.emplace<datetime>(v); return *this; }
|
||||
field& operator=(const time& v) noexcept { repr_.data.emplace<time>(v); return *this; }
|
||||
field& operator=(const field_view& v) { from_view(v); return *this; }
|
||||
|
||||
field_kind kind() const noexcept { return static_cast<field_kind>(repr_.index()); }
|
||||
field_kind kind() const noexcept { return repr_.kind(); }
|
||||
|
||||
bool is_null() const noexcept { return kind() == field_kind::null; }
|
||||
bool is_int64() const noexcept { return kind() == field_kind::int64; }
|
||||
@@ -82,41 +83,41 @@ public:
|
||||
bool is_datetime() const noexcept { return kind() == field_kind::datetime; }
|
||||
bool is_time() const noexcept { return kind() == field_kind::time; }
|
||||
|
||||
const std::int64_t& as_int64() const { return internal_as<std::int64_t>(); }
|
||||
const std::uint64_t& as_uint64() const { return internal_as<std::uint64_t>(); }
|
||||
const std::string& as_string() const { return internal_as<std::string>(); }
|
||||
const float& as_float() const { return internal_as<float>(); }
|
||||
const double& as_double() const { return internal_as<double>(); }
|
||||
const date& as_date() const { return internal_as<date>(); }
|
||||
const datetime& as_datetime() const { return internal_as<datetime>(); }
|
||||
const time& as_time() const { return internal_as<time>(); }
|
||||
const std::int64_t& as_int64() const { return repr_.as<std::int64_t>(); }
|
||||
const std::uint64_t& as_uint64() const { return repr_.as<std::uint64_t>(); }
|
||||
const std::string& as_string() const { return repr_.as<std::string>(); }
|
||||
const float& as_float() const { return repr_.as<float>(); }
|
||||
const double& as_double() const { return repr_.as<double>(); }
|
||||
const date& as_date() const { return repr_.as<date>(); }
|
||||
const datetime& as_datetime() const { return repr_.as<datetime>(); }
|
||||
const time& as_time() const { return repr_.as<time>(); }
|
||||
|
||||
std::int64_t& as_int64() { return internal_as<std::int64_t>(); }
|
||||
std::uint64_t& as_uint64() { return internal_as<std::uint64_t>(); }
|
||||
std::string& as_string() { return internal_as<std::string>(); }
|
||||
float& as_float() { return internal_as<float>(); }
|
||||
double& as_double() { return internal_as<double>(); }
|
||||
date& as_date() { return internal_as<date>(); }
|
||||
datetime& as_datetime() { return internal_as<datetime>(); }
|
||||
time& as_time() { return internal_as<time>(); }
|
||||
std::int64_t& as_int64() { return repr_.as<std::int64_t>(); }
|
||||
std::uint64_t& as_uint64() { return repr_.as<std::uint64_t>(); }
|
||||
std::string& as_string() { return repr_.as<std::string>(); }
|
||||
float& as_float() { return repr_.as<float>(); }
|
||||
double& as_double() { return repr_.as<double>(); }
|
||||
date& as_date() { return repr_.as<date>(); }
|
||||
datetime& as_datetime() { return repr_.as<datetime>(); }
|
||||
time& as_time() { return repr_.as<time>(); }
|
||||
|
||||
const std::int64_t& get_int64() const noexcept { return internal_get<std::int64_t>(); }
|
||||
const std::uint64_t& get_uint64() const noexcept { return internal_get<std::uint64_t>(); }
|
||||
const std::string& get_string() const noexcept { return internal_get<std::string>(); }
|
||||
const float& get_float() const noexcept { return internal_get<float>(); }
|
||||
const double& get_double() const noexcept { return internal_get<double>(); }
|
||||
const date& get_date() const noexcept { return internal_get<date>(); }
|
||||
const datetime& get_datetime() const noexcept { return internal_get<datetime>(); }
|
||||
const time& get_time() const noexcept { return internal_get<time>(); }
|
||||
const std::int64_t& get_int64() const noexcept { return repr_.get<std::int64_t>(); }
|
||||
const std::uint64_t& get_uint64() const noexcept { return repr_.get<std::uint64_t>(); }
|
||||
const std::string& get_string() const noexcept { return repr_.get<std::string>(); }
|
||||
const float& get_float() const noexcept { return repr_.get<float>(); }
|
||||
const double& get_double() const noexcept { return repr_.get<double>(); }
|
||||
const date& get_date() const noexcept { return repr_.get<date>(); }
|
||||
const datetime& get_datetime() const noexcept { return repr_.get<datetime>(); }
|
||||
const time& get_time() const noexcept { return repr_.get<time>(); }
|
||||
|
||||
std::int64_t& get_int64() noexcept { return internal_get<std::int64_t>(); }
|
||||
std::uint64_t& get_uint64() noexcept { return internal_get<std::uint64_t>(); }
|
||||
std::string& get_string() noexcept { return internal_get<std::string>(); }
|
||||
float& get_float() noexcept { return internal_get<float>(); }
|
||||
double& get_double() noexcept { return internal_get<double>(); }
|
||||
date& get_date() noexcept { return internal_get<date>(); }
|
||||
datetime& get_datetime() noexcept { return internal_get<datetime>(); }
|
||||
time& get_time() noexcept { return internal_get<time>(); }
|
||||
std::int64_t& get_int64() noexcept { return repr_.get<std::int64_t>(); }
|
||||
std::uint64_t& get_uint64() noexcept { return repr_.get<std::uint64_t>(); }
|
||||
std::string& get_string() noexcept { return repr_.get<std::string>(); }
|
||||
float& get_float() noexcept { return repr_.get<float>(); }
|
||||
double& get_double() noexcept { return repr_.get<double>(); }
|
||||
date& get_date() noexcept { return repr_.get<date>(); }
|
||||
datetime& get_datetime() noexcept { return repr_.get<datetime>(); }
|
||||
time& get_time() noexcept { return repr_.get<time>(); }
|
||||
|
||||
void emplace_null() noexcept { *this = nullptr; }
|
||||
void emplace_int64(std::int64_t v) noexcept { *this = v; }
|
||||
@@ -128,38 +129,12 @@ public:
|
||||
void emplace_datetime(const datetime& v) noexcept { *this = v; }
|
||||
void emplace_time(const time& v) noexcept { *this = v; }
|
||||
|
||||
inline operator field_view() const noexcept;
|
||||
inline operator field_view() const noexcept { return field_view(&repr_); }
|
||||
|
||||
bool operator==(const field& rhs) const noexcept { return field_view(*this) == field_view(rhs); }
|
||||
bool operator!=(const field& rhs) const noexcept { return !(*this == rhs); }
|
||||
private:
|
||||
using null_t = boost::variant2::monostate;
|
||||
|
||||
using variant_type = boost::variant2::variant<
|
||||
null_t, // Any of the below when the value is NULL
|
||||
std::int64_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
|
||||
std::uint64_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, YEAR, BIT
|
||||
std::string, // CHAR, VARCHAR, BINARY, VARBINARY, TEXT (all sizes), BLOB (all sizes), ENUM, SET, DECIMAL, GEOMTRY
|
||||
float, // FLOAT
|
||||
double, // DOUBLE
|
||||
date, // DATE
|
||||
datetime, // DATETIME, TIMESTAMP
|
||||
time // TIME
|
||||
>;
|
||||
|
||||
variant_type repr_;
|
||||
|
||||
template <typename T>
|
||||
const T& internal_as() const;
|
||||
|
||||
template <typename T>
|
||||
T& internal_as();
|
||||
|
||||
template <typename T>
|
||||
const T& internal_get() const noexcept;
|
||||
|
||||
template <typename T>
|
||||
T& internal_get() noexcept;
|
||||
detail::field_impl repr_;
|
||||
|
||||
inline void from_view(const field_view& v);
|
||||
};
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#ifndef BOOST_MYSQL_FIELD_VIEW_HPP
|
||||
#define BOOST_MYSQL_FIELD_VIEW_HPP
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/field_impl.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <array>
|
||||
@@ -48,29 +49,37 @@ public:
|
||||
* Caution: `value(NULL)` will __NOT__ match this overload. It will try to construct
|
||||
* a `boost::string_view` from a NULL C string, causing undefined behavior.
|
||||
*/
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(std::nullptr_t) noexcept : repr_(null_t()) {}
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(std::nullptr_t) noexcept {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR field_view(signed char v) noexcept : repr_(std::int64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(short v) noexcept : repr_(std::int64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(int v) noexcept : repr_(std::int64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(long v) noexcept : repr_(std::int64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(long long v) noexcept : repr_(std::int64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(signed char v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(short v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(int v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(long v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(long long v) noexcept;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR field_view(unsigned char v) noexcept : repr_(std::uint64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(unsigned short v) noexcept : repr_(std::uint64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(unsigned int v) noexcept : repr_(std::uint64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(unsigned long v) noexcept : repr_(std::uint64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(unsigned long long v) noexcept : repr_(std::uint64_t(v)) {}
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(unsigned char v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(unsigned short v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(unsigned int v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(unsigned long v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(unsigned long long v) noexcept;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR field_view(boost::string_view v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(float v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(double v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(const date& v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(const datetime& v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR field_view(const time& v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(boost::string_view v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(float v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(double v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(const date& v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(const datetime& v) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline field_view(const time& v) noexcept;
|
||||
|
||||
// TODO: hide this
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(detail::string_view_offset v) noexcept : repr_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(detail::string_view_offset v) noexcept : ikind_(internal_kind::sv_offset)
|
||||
{
|
||||
repr_.sv_offset = { v.offset(), v.size() };
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(const detail::field_impl* v) noexcept : ikind_(internal_kind::field_ptr)
|
||||
{
|
||||
repr_.field_ptr = v;
|
||||
}
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline field_kind kind() const noexcept;
|
||||
|
||||
@@ -84,23 +93,23 @@ public:
|
||||
BOOST_CXX14_CONSTEXPR bool is_datetime() const noexcept { return kind() == field_kind::datetime; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_time() const noexcept { return kind() == field_kind::time; }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t as_int64() const { return internal_as<std::int64_t>(); }
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t as_uint64() const { return internal_as<std::uint64_t>(); }
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view as_string() const { return internal_as<boost::string_view>(); }
|
||||
BOOST_CXX14_CONSTEXPR float as_float() const { return internal_as<float>(); }
|
||||
BOOST_CXX14_CONSTEXPR double as_double() const { return internal_as<double>(); }
|
||||
BOOST_CXX14_CONSTEXPR date as_date() const { return internal_as<date>(); }
|
||||
BOOST_CXX14_CONSTEXPR datetime as_datetime() const { return internal_as<datetime>(); }
|
||||
BOOST_CXX14_CONSTEXPR time as_time() const { return internal_as<time>(); }
|
||||
BOOST_CXX14_CONSTEXPR inline std::int64_t as_int64() const;
|
||||
BOOST_CXX14_CONSTEXPR inline std::uint64_t as_uint64() const;
|
||||
BOOST_CXX14_CONSTEXPR inline boost::string_view as_string() const;
|
||||
BOOST_CXX14_CONSTEXPR inline float as_float() const;
|
||||
BOOST_CXX14_CONSTEXPR inline double as_double() const;
|
||||
BOOST_CXX14_CONSTEXPR inline date as_date() const;
|
||||
BOOST_CXX14_CONSTEXPR inline datetime as_datetime() const;
|
||||
BOOST_CXX14_CONSTEXPR inline time as_time() const;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t get_int64() const noexcept { return internal_get<std::int64_t>(); }
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t get_uint64() const noexcept { return internal_get<std::uint64_t>(); }
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view get_string() const noexcept { return internal_get<boost::string_view>(); }
|
||||
BOOST_CXX14_CONSTEXPR float get_float() const noexcept { return internal_get<float>(); }
|
||||
BOOST_CXX14_CONSTEXPR double get_double() const noexcept { return internal_get<double>(); }
|
||||
BOOST_CXX14_CONSTEXPR date get_date() const noexcept { return internal_get<date>(); }
|
||||
BOOST_CXX14_CONSTEXPR datetime get_datetime() const noexcept { return internal_get<datetime>(); }
|
||||
BOOST_CXX14_CONSTEXPR time get_time() const noexcept { return internal_get<time>(); }
|
||||
BOOST_CXX14_CONSTEXPR inline std::int64_t get_int64() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline std::uint64_t get_uint64() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline boost::string_view get_string() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline float get_float() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline double get_double() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline date get_date() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline datetime get_datetime() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline time get_time() const noexcept;
|
||||
|
||||
/// Tests for equality (type and value); see [link mysql.values.relational this section] for more info.
|
||||
BOOST_CXX14_CONSTEXPR bool operator==(const field_view& rhs) const noexcept;
|
||||
@@ -111,39 +120,65 @@ public:
|
||||
// TODO: hide this
|
||||
void offset_to_string_view(const std::uint8_t* buffer_first) noexcept
|
||||
{
|
||||
auto* sv_index = boost::variant2::get_if<detail::string_view_offset>(&repr_);
|
||||
if (sv_index)
|
||||
if (ikind_ == internal_kind::sv_offset)
|
||||
{
|
||||
repr_ = sv_index->to_string_view(reinterpret_cast<const char*>(buffer_first));
|
||||
ikind_ = internal_kind::string;
|
||||
repr_.string = {
|
||||
reinterpret_cast<const char*>(buffer_first) + repr_.sv_offset.offset,
|
||||
repr_.sv_offset.size
|
||||
};
|
||||
}
|
||||
}
|
||||
private:
|
||||
struct print_visitor;
|
||||
enum class internal_kind
|
||||
{
|
||||
null = 0,
|
||||
int64,
|
||||
uint64,
|
||||
string,
|
||||
float_,
|
||||
double_,
|
||||
date,
|
||||
datetime,
|
||||
time,
|
||||
sv_offset,
|
||||
field_ptr
|
||||
};
|
||||
|
||||
union repr_t
|
||||
{
|
||||
std::int64_t int64;
|
||||
std::uint64_t uint64;
|
||||
struct
|
||||
{
|
||||
const char* ptr;
|
||||
std::size_t size;
|
||||
} string;
|
||||
float float_;
|
||||
double double_;
|
||||
date::rep date_;
|
||||
datetime::rep datetime_;
|
||||
time::rep time_;
|
||||
struct
|
||||
{
|
||||
std::size_t offset;
|
||||
std::size_t size;
|
||||
} sv_offset;
|
||||
const detail::field_impl* field_ptr;
|
||||
|
||||
boost::string_view get_string() const noexcept { return boost::string_view(string.ptr, string.size); }
|
||||
date get_date() const noexcept { return date(date::duration(date_));}
|
||||
datetime get_datetime() const noexcept { return datetime(datetime::duration(datetime_)); }
|
||||
time get_time() const noexcept { return time(time_); }
|
||||
};
|
||||
|
||||
internal_kind ikind_ { internal_kind::null };
|
||||
repr_t repr_;
|
||||
|
||||
using null_t = boost::variant2::monostate;
|
||||
|
||||
using variant_type = boost::variant2::variant<
|
||||
null_t, // Any of the below when the value is NULL
|
||||
std::int64_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
|
||||
std::uint64_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, YEAR, BIT
|
||||
boost::string_view,// CHAR, VARCHAR, BINARY, VARBINARY, TEXT (all sizes), BLOB (all sizes), ENUM, SET, DECIMAL, GEOMTRY
|
||||
float, // FLOAT
|
||||
double, // DOUBLE
|
||||
date, // DATE
|
||||
datetime, // DATETIME, TIMESTAMP
|
||||
time, // TIME
|
||||
detail::string_view_offset // Used during parsing, not exposed to the user
|
||||
>;
|
||||
|
||||
variant_type repr_;
|
||||
|
||||
template <typename T>
|
||||
const T& internal_as() const;
|
||||
|
||||
template <typename T>
|
||||
const T& internal_get() const noexcept;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const field_view& v);
|
||||
|
||||
bool is_field_ptr() const noexcept { return ikind_ == internal_kind::field_ptr; }
|
||||
inline void check_kind(internal_kind expected) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#ifndef BOOST_MYSQL_IMPL_FIELD_HPP
|
||||
#define BOOST_MYSQL_IMPL_FIELD_HPP
|
||||
|
||||
#include "boost/mysql/field_view.hpp"
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/field.hpp>
|
||||
@@ -23,70 +22,18 @@ void boost::mysql::field::from_view(
|
||||
{
|
||||
switch (fv.kind())
|
||||
{
|
||||
case field_kind::null: repr_.emplace<null_t>(null_t()); break;
|
||||
case field_kind::int64: repr_.emplace<std::int64_t>(fv.get_int64()); break;
|
||||
case field_kind::uint64: repr_.emplace<std::uint64_t>(fv.get_uint64()); break;
|
||||
case field_kind::string: repr_.emplace<std::string>(fv.get_string()); break;
|
||||
case field_kind::float_: repr_.emplace<float>(fv.get_float()); break;
|
||||
case field_kind::double_: repr_.emplace<double>(fv.get_double()); break;
|
||||
case field_kind::date: repr_.emplace<date>(fv.get_date()); break;
|
||||
case field_kind::datetime: repr_.emplace<datetime>(fv.get_datetime()); break;
|
||||
case field_kind::time: repr_.emplace<time>(fv.get_time()); break;
|
||||
case field_kind::null: repr_.data.emplace<detail::field_impl::null_t>(); break;
|
||||
case field_kind::int64: repr_.data.emplace<std::int64_t>(fv.get_int64()); break;
|
||||
case field_kind::uint64: repr_.data.emplace<std::uint64_t>(fv.get_uint64()); break;
|
||||
case field_kind::string: repr_.data.emplace<std::string>(fv.get_string()); break;
|
||||
case field_kind::float_: repr_.data.emplace<float>(fv.get_float()); break;
|
||||
case field_kind::double_: repr_.data.emplace<double>(fv.get_double()); break;
|
||||
case field_kind::date: repr_.data.emplace<date>(fv.get_date()); break;
|
||||
case field_kind::datetime: repr_.data.emplace<datetime>(fv.get_datetime()); break;
|
||||
case field_kind::time: repr_.data.emplace<time>(fv.get_time()); break;
|
||||
}
|
||||
}
|
||||
|
||||
inline boost::mysql::field::operator field_view() const noexcept
|
||||
{
|
||||
switch (kind())
|
||||
{
|
||||
case field_kind::null: return field_view();
|
||||
case field_kind::int64: return field_view(get_int64());
|
||||
case field_kind::uint64: return field_view(get_uint64());
|
||||
case field_kind::string: return field_view(get_string());
|
||||
case field_kind::float_: return field_view(get_float());
|
||||
case field_kind::double_: return field_view(get_double());
|
||||
case field_kind::date: return field_view(get_date());
|
||||
case field_kind::datetime: return field_view(get_datetime());
|
||||
case field_kind::time: return field_view(get_time());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& boost::mysql::field::internal_as() const
|
||||
{
|
||||
const T* res = boost::variant2::get_if<T>(&repr_);
|
||||
if (!res)
|
||||
throw bad_field_access();
|
||||
return *res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& boost::mysql::field::internal_as()
|
||||
{
|
||||
T* res = boost::variant2::get_if<T>(&repr_);
|
||||
if (!res)
|
||||
throw bad_field_access();
|
||||
return *res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& boost::mysql::field::internal_get() const noexcept
|
||||
{
|
||||
// TODO: this can be done better
|
||||
const T* res = boost::variant2::get_if<T>(&repr_);
|
||||
assert(res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& boost::mysql::field::internal_get() noexcept
|
||||
{
|
||||
// TODO: this can be done better
|
||||
T* res = boost::variant2::get_if<T>(&repr_);
|
||||
assert(res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
inline std::ostream& boost::mysql::operator<<(
|
||||
std::ostream& os,
|
||||
const field& value
|
||||
|
||||
@@ -12,110 +12,386 @@
|
||||
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/bad_field_access.hpp>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
|
||||
struct boost::mysql::field_view::print_visitor
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
inline std::ostream& print_date(std::ostream& os, const date& value)
|
||||
{
|
||||
std::ostream& os;
|
||||
assert(value >= min_date && value <= max_date);
|
||||
auto ymd = detail::days_to_ymd(value.time_since_epoch().count());
|
||||
char buffer [32] {};
|
||||
snprintf(buffer, sizeof(buffer), "%04d-%02u-%02u", ymd.years, ymd.month, ymd.day);
|
||||
os << buffer;
|
||||
return os;
|
||||
}
|
||||
|
||||
print_visitor(std::ostream& os): os(os) {};
|
||||
inline std::ostream& print_time(std::ostream& os, const time& value)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
assert(value >= min_time && value <= max_time);
|
||||
char buffer [64] {};
|
||||
const char* sign = value < microseconds(0) ? "-" : "";
|
||||
auto num_micros = value % seconds(1);
|
||||
auto num_secs = duration_cast<seconds>(value % minutes(1) - num_micros);
|
||||
auto num_mins = duration_cast<minutes>(value % hours(1) - num_secs);
|
||||
auto num_hours = duration_cast<hours>(value - num_mins);
|
||||
|
||||
template <class T>
|
||||
void operator()(const T& value) const { os << value; }
|
||||
snprintf(buffer, sizeof(buffer), "%s%02d:%02u:%02u.%06u",
|
||||
sign,
|
||||
static_cast<int>(std::abs(num_hours.count())),
|
||||
static_cast<unsigned>(std::abs(num_mins.count())),
|
||||
static_cast<unsigned>(std::abs(num_secs.count())),
|
||||
static_cast<unsigned>(std::abs(num_micros.count()))
|
||||
);
|
||||
|
||||
void operator()(const date& value) const
|
||||
{
|
||||
assert(value >= min_date && value <= max_date);
|
||||
auto ymd = detail::days_to_ymd(value.time_since_epoch().count());
|
||||
char buffer [32] {};
|
||||
snprintf(buffer, sizeof(buffer), "%04d-%02u-%02u", ymd.years, ymd.month, ymd.day);
|
||||
os << buffer;
|
||||
}
|
||||
void operator()(const datetime& value) const
|
||||
{
|
||||
using namespace std::chrono;
|
||||
date date_part = time_point_cast<days>(value);
|
||||
if (date_part > value)
|
||||
date_part -= days(1);
|
||||
auto tod = value - date_part;
|
||||
(*this)(date_part); // date part
|
||||
os << ' '; // separator
|
||||
(*this)(duration_cast<time>(tod)); // time of day part
|
||||
}
|
||||
void operator()(const time& value) const
|
||||
{
|
||||
using namespace std::chrono;
|
||||
assert(value >= min_time && value <= max_time);
|
||||
char buffer [64] {};
|
||||
const char* sign = value < microseconds(0) ? "-" : "";
|
||||
auto num_micros = value % seconds(1);
|
||||
auto num_secs = duration_cast<seconds>(value % minutes(1) - num_micros);
|
||||
auto num_mins = duration_cast<minutes>(value % hours(1) - num_secs);
|
||||
auto num_hours = duration_cast<hours>(value - num_mins);
|
||||
os << buffer;
|
||||
return os;
|
||||
}
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s%02d:%02u:%02u.%06u",
|
||||
sign,
|
||||
static_cast<int>(std::abs(num_hours.count())),
|
||||
static_cast<unsigned>(std::abs(num_mins.count())),
|
||||
static_cast<unsigned>(std::abs(num_secs.count())),
|
||||
static_cast<unsigned>(std::abs(num_micros.count()))
|
||||
);
|
||||
inline std::ostream& print_datetime(std::ostream& os, const datetime& value)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
date date_part = time_point_cast<days>(value);
|
||||
if (date_part > value)
|
||||
date_part -= days(1);
|
||||
auto tod = value - date_part;
|
||||
print_date(os, date_part); // date part
|
||||
os << ' '; // separator
|
||||
print_time(os, duration_cast<time>(tod)); // time of day part
|
||||
return os;
|
||||
}
|
||||
|
||||
os << buffer;
|
||||
}
|
||||
void operator()(null_t) const { os << "<NULL>"; }
|
||||
void operator()(detail::string_view_offset) const { os << "<invalid>"; }
|
||||
};
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
signed char v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64)
|
||||
{
|
||||
repr_.int64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
short v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64)
|
||||
{
|
||||
repr_.int64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
int v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64)
|
||||
{
|
||||
repr_.int64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64)
|
||||
{
|
||||
repr_.int64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
long long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64)
|
||||
{
|
||||
repr_.int64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned char v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64)
|
||||
{
|
||||
repr_.uint64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned short v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64)
|
||||
{
|
||||
repr_.uint64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned int v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64)
|
||||
{
|
||||
repr_.uint64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64)
|
||||
{
|
||||
repr_.uint64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned long long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64)
|
||||
{
|
||||
repr_.uint64 = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
boost::string_view v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::string)
|
||||
{
|
||||
repr_.string = { v.data(), v.size()};
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
float v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::float_)
|
||||
{
|
||||
repr_.float_ = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
double v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::double_)
|
||||
{
|
||||
repr_.double_ = v;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
const date& v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::date)
|
||||
{
|
||||
repr_.date_ = v.time_since_epoch().count();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
const datetime& v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::datetime)
|
||||
{
|
||||
repr_.datetime_ = v.time_since_epoch().count();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
const time& v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::time)
|
||||
{
|
||||
repr_.time_ = v.count();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::field_view::kind() const noexcept
|
||||
{
|
||||
// Indices below time are user-facing; indices above that are used
|
||||
// by the library during parsing, but never reach the user
|
||||
assert(repr_.index() <= static_cast<int>(field_kind::time));
|
||||
return static_cast<field_kind>(repr_.index());
|
||||
switch (ikind_)
|
||||
{
|
||||
case internal_kind::null: return field_kind::null;
|
||||
case internal_kind::int64: return field_kind::int64;
|
||||
case internal_kind::uint64: return field_kind::uint64;
|
||||
case internal_kind::string: return field_kind::string;
|
||||
case internal_kind::float_: return field_kind::float_;
|
||||
case internal_kind::double_: return field_kind::double_;
|
||||
case internal_kind::date: return field_kind::date;
|
||||
case internal_kind::datetime: return field_kind::datetime;
|
||||
case internal_kind::time: return field_kind::time;
|
||||
case internal_kind::field_ptr: return repr_.field_ptr->kind();
|
||||
// sv_offset values must be converted via offset_to_string_view before calling any other fn
|
||||
default: assert(false); return field_kind::null;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& boost::mysql::field_view::internal_as() const
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t
|
||||
boost::mysql::field_view::as_int64() const
|
||||
{
|
||||
const T* res = boost::variant2::get_if<T>(&repr_);
|
||||
if (!res)
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<std::int64_t>();
|
||||
check_kind(internal_kind::int64);
|
||||
return repr_.int64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t
|
||||
boost::mysql::field_view::as_uint64() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<std::uint64_t>();
|
||||
check_kind(internal_kind::uint64);
|
||||
return repr_.uint64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view
|
||||
boost::mysql::field_view::as_string() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<std::string>();
|
||||
check_kind(internal_kind::string);
|
||||
return repr_.get_string();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR float
|
||||
boost::mysql::field_view::as_float() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<float>();
|
||||
check_kind(internal_kind::float_);
|
||||
return repr_.float_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR double
|
||||
boost::mysql::field_view::as_double() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<double>();
|
||||
check_kind(internal_kind::double_);
|
||||
return repr_.double_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::date
|
||||
boost::mysql::field_view::as_date() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<date>();
|
||||
check_kind(internal_kind::date);
|
||||
return repr_.get_date();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::datetime
|
||||
boost::mysql::field_view::as_datetime() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<datetime>();
|
||||
check_kind(internal_kind::datetime);
|
||||
return repr_.get_datetime();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::time
|
||||
boost::mysql::field_view::as_time() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<time>();
|
||||
check_kind(internal_kind::time);
|
||||
return repr_.get_time();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t
|
||||
boost::mysql::field_view::get_int64() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<std::int64_t>() : repr_.int64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t
|
||||
boost::mysql::field_view::get_uint64() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<std::uint64_t>() : repr_.uint64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view
|
||||
boost::mysql::field_view::get_string() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? boost::string_view(repr_.field_ptr->get<std::string>()) : repr_.get_string();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR float
|
||||
boost::mysql::field_view::get_float() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<float>() : repr_.float_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR double
|
||||
boost::mysql::field_view::get_double() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<double>() : repr_.double_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::date
|
||||
boost::mysql::field_view::get_date() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<date>() : repr_.get_date();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::datetime
|
||||
boost::mysql::field_view::get_datetime() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<datetime>() : repr_.get_datetime();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::time
|
||||
boost::mysql::field_view::get_time() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<time>() : repr_.get_time();
|
||||
}
|
||||
|
||||
void boost::mysql::field_view::check_kind(
|
||||
internal_kind expected
|
||||
) const
|
||||
{
|
||||
if (ikind_ != expected)
|
||||
throw bad_field_access();
|
||||
return *res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& boost::mysql::field_view::internal_get() const noexcept
|
||||
{
|
||||
const T* res = boost::variant2::get_if<T>(&repr_);
|
||||
assert(res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(
|
||||
const field_view& rhs
|
||||
) const noexcept
|
||||
{
|
||||
if (is_int64() && rhs.is_uint64())
|
||||
auto k = kind(), rhs_k = rhs.kind();
|
||||
switch (k)
|
||||
{
|
||||
std::int64_t this_val = get_int64();
|
||||
if (this_val < 0)
|
||||
case field_kind::null: return rhs_k == field_kind::null;
|
||||
case field_kind::int64:
|
||||
if (rhs_k == field_kind::int64)
|
||||
return get_int64() == rhs.get_int64();
|
||||
else if (rhs_k == field_kind::uint64)
|
||||
{
|
||||
std::int64_t this_val = get_int64();
|
||||
if (this_val < 0)
|
||||
return false;
|
||||
else
|
||||
return static_cast<std::uint64_t>(this_val) == rhs.get_uint64();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return static_cast<std::uint64_t>(this_val) == rhs.get_uint64();
|
||||
}
|
||||
else if (is_uint64() && rhs.is_int64())
|
||||
{
|
||||
std::int64_t rhs_val = rhs.get_int64();
|
||||
if (rhs_val < 0)
|
||||
case field_kind::uint64:
|
||||
if (rhs_k == field_kind::uint64)
|
||||
return get_uint64() == rhs.get_uint64();
|
||||
else if (rhs_k == field_kind::int64)
|
||||
{
|
||||
std::int64_t rhs_val = rhs.get_int64();
|
||||
if (rhs_val < 0)
|
||||
return false;
|
||||
else
|
||||
return static_cast<std::uint64_t>(rhs_val) == get_uint64();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return static_cast<std::uint64_t>(rhs_val) == get_uint64();
|
||||
}
|
||||
else
|
||||
{
|
||||
return repr_ == rhs.repr_;
|
||||
case field_kind::string:
|
||||
return rhs_k == field_kind::string && get_string() == rhs.get_string();
|
||||
case field_kind::float_:
|
||||
return rhs_k == field_kind::float_ && get_float() == rhs.get_float();
|
||||
case field_kind::double_:
|
||||
return rhs_k == field_kind::double_ && get_double() == rhs.get_double();
|
||||
case field_kind::date:
|
||||
return rhs_k == field_kind::date && get_date() == rhs.get_date();
|
||||
case field_kind::datetime:
|
||||
return rhs_k == field_kind::datetime && get_datetime() == rhs.get_datetime();
|
||||
case field_kind::time:
|
||||
return rhs_k == field_kind::time && get_time() == rhs.get_time();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +401,18 @@ inline std::ostream& boost::mysql::operator<<(
|
||||
const field_view& value
|
||||
)
|
||||
{
|
||||
boost::variant2::visit(field_view::print_visitor(os), value.repr_);
|
||||
return os;
|
||||
switch (value.kind())
|
||||
{
|
||||
case field_kind::null: return os << "<NULL>";
|
||||
case field_kind::int64: return os << value.get_int64();
|
||||
case field_kind::uint64: return os << value.get_uint64();
|
||||
case field_kind::string: return os << value.get_string();
|
||||
case field_kind::float_: return os << value.get_float();
|
||||
case field_kind::double_: return os << value.get_double();
|
||||
case field_kind::date: return detail::print_date(os, value.get_date());
|
||||
case field_kind::datetime: return detail::print_datetime(os, value.get_datetime());
|
||||
case field_kind::time: return detail::print_time(os, value.get_time());
|
||||
}
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
@@ -139,4 +425,5 @@ boost::mysql::make_field_views(
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user