mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-07 16:07:53 +00:00
Added thirdparty: boost library
This commit is contained in:
Vendored
Executable
+217
@@ -0,0 +1,217 @@
|
||||
//
|
||||
// Copyright (c) 2019-2023 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_EXECUTION_PROCESSOR_EXECUTION_PROCESSOR_HPP
|
||||
#define BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_EXECUTION_PROCESSOR_HPP
|
||||
|
||||
#include <boost/mysql/diagnostics.hpp>
|
||||
#include <boost/mysql/error_code.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/metadata_mode.hpp>
|
||||
#include <boost/mysql/string_view.hpp>
|
||||
|
||||
#include <boost/mysql/detail/access.hpp>
|
||||
#include <boost/mysql/detail/coldef_view.hpp>
|
||||
#include <boost/mysql/detail/ok_view.hpp>
|
||||
#include <boost/mysql/detail/resultset_encoding.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/span.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
// A type-erased reference to be used as the output range for static_execution_state
|
||||
class output_ref
|
||||
{
|
||||
// Pointer to the first element of the span
|
||||
void* data_{};
|
||||
|
||||
// Number of elements in the span
|
||||
std::size_t max_size_{(std::numeric_limits<std::size_t>::max)()};
|
||||
|
||||
// Identifier for the type of elements. Index in the resultset type list
|
||||
std::size_t type_index_{};
|
||||
|
||||
// Offset into the span's data (static_execution_state). Otherwise unused
|
||||
std::size_t offset_{};
|
||||
|
||||
public:
|
||||
constexpr output_ref() noexcept = default;
|
||||
|
||||
template <class T>
|
||||
constexpr output_ref(boost::span<T> span, std::size_t type_index, std::size_t offset = 0) noexcept
|
||||
: data_(span.data()), max_size_(span.size()), type_index_(type_index), offset_(offset)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t max_size() const noexcept { return max_size_; }
|
||||
std::size_t type_index() const noexcept { return type_index_; }
|
||||
std::size_t offset() const noexcept { return offset_; }
|
||||
void set_offset(std::size_t v) noexcept { offset_ = v; }
|
||||
|
||||
template <class T>
|
||||
T& span_element() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(data_);
|
||||
return static_cast<T*>(data_)[offset_];
|
||||
}
|
||||
};
|
||||
|
||||
class execution_processor
|
||||
{
|
||||
public:
|
||||
virtual ~execution_processor() {}
|
||||
|
||||
void reset(resultset_encoding enc, metadata_mode mode) noexcept
|
||||
{
|
||||
state_ = state_t::reading_first;
|
||||
encoding_ = enc;
|
||||
mode_ = mode;
|
||||
seqnum_ = 0;
|
||||
remaining_meta_ = 0;
|
||||
reset_impl();
|
||||
}
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD
|
||||
error_code on_head_ok_packet(const ok_view& pack, diagnostics& diag)
|
||||
{
|
||||
BOOST_ASSERT(is_reading_head());
|
||||
auto err = on_head_ok_packet_impl(pack, diag);
|
||||
set_state_for_ok(pack);
|
||||
return err;
|
||||
}
|
||||
|
||||
void on_num_meta(std::size_t num_columns)
|
||||
{
|
||||
BOOST_ASSERT(is_reading_head());
|
||||
on_num_meta_impl(num_columns);
|
||||
remaining_meta_ = num_columns;
|
||||
set_state(state_t::reading_metadata);
|
||||
}
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD
|
||||
error_code on_meta(const coldef_view& pack, diagnostics& diag)
|
||||
{
|
||||
BOOST_ASSERT(is_reading_meta());
|
||||
bool is_last = --remaining_meta_ == 0;
|
||||
auto err = on_meta_impl(pack, is_last, diag);
|
||||
if (is_last)
|
||||
set_state(state_t::reading_rows);
|
||||
return err;
|
||||
}
|
||||
|
||||
void on_row_batch_start()
|
||||
{
|
||||
BOOST_ASSERT(is_reading_rows());
|
||||
on_row_batch_start_impl();
|
||||
}
|
||||
|
||||
void on_row_batch_finish() { on_row_batch_finish_impl(); }
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD
|
||||
error_code on_row(span<const std::uint8_t> msg, const output_ref& ref, std::vector<field_view>& storage)
|
||||
{
|
||||
BOOST_ASSERT(is_reading_rows());
|
||||
return on_row_impl(msg, ref, storage);
|
||||
}
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD
|
||||
error_code on_row_ok_packet(const ok_view& pack)
|
||||
{
|
||||
BOOST_ASSERT(is_reading_rows());
|
||||
auto err = on_row_ok_packet_impl(pack);
|
||||
set_state_for_ok(pack);
|
||||
return err;
|
||||
}
|
||||
|
||||
bool is_reading_first() const noexcept { return state_ == state_t::reading_first; }
|
||||
bool is_reading_first_subseq() const noexcept { return state_ == state_t::reading_first_subseq; }
|
||||
bool is_reading_head() const noexcept
|
||||
{
|
||||
return state_ == state_t::reading_first || state_ == state_t::reading_first_subseq;
|
||||
}
|
||||
bool is_reading_meta() const noexcept { return state_ == state_t::reading_metadata; }
|
||||
bool is_reading_rows() const noexcept { return state_ == state_t::reading_rows; }
|
||||
bool is_complete() const noexcept { return state_ == state_t::complete; }
|
||||
|
||||
resultset_encoding encoding() const noexcept { return encoding_; }
|
||||
std::uint8_t& sequence_number() noexcept { return seqnum_; }
|
||||
metadata_mode meta_mode() const noexcept { return mode_; }
|
||||
|
||||
protected:
|
||||
virtual void reset_impl() noexcept = 0;
|
||||
virtual error_code on_head_ok_packet_impl(const ok_view& pack, diagnostics& diag) = 0;
|
||||
virtual void on_num_meta_impl(std::size_t num_columns) = 0;
|
||||
virtual error_code on_meta_impl(const coldef_view& coldef, bool is_last, diagnostics& diag) = 0;
|
||||
virtual error_code on_row_ok_packet_impl(const ok_view& pack) = 0;
|
||||
virtual error_code on_row_impl(
|
||||
span<const std::uint8_t> msg,
|
||||
const output_ref& ref,
|
||||
std::vector<field_view>& storage
|
||||
) = 0;
|
||||
virtual void on_row_batch_start_impl() = 0;
|
||||
virtual void on_row_batch_finish_impl() = 0;
|
||||
|
||||
metadata create_meta(const coldef_view& coldef) const
|
||||
{
|
||||
return access::construct<metadata>(coldef, mode_ == metadata_mode::full);
|
||||
}
|
||||
|
||||
private:
|
||||
enum class state_t
|
||||
{
|
||||
// waiting for 1st packet, for the 1st resultset
|
||||
reading_first,
|
||||
|
||||
// same, but for subsequent resultsets (distiguised to provide a cleaner xp to
|
||||
// the user in (static_)execution_state)
|
||||
reading_first_subseq,
|
||||
|
||||
// waiting for metadata packets
|
||||
reading_metadata,
|
||||
|
||||
// waiting for rows
|
||||
reading_rows,
|
||||
|
||||
// done
|
||||
complete
|
||||
};
|
||||
|
||||
state_t state_{state_t::reading_first};
|
||||
resultset_encoding encoding_{resultset_encoding::text};
|
||||
std::uint8_t seqnum_{};
|
||||
metadata_mode mode_{metadata_mode::minimal};
|
||||
std::size_t remaining_meta_{};
|
||||
|
||||
void set_state(state_t v) noexcept { state_ = v; }
|
||||
|
||||
void set_state_for_ok(const ok_view& pack) noexcept
|
||||
{
|
||||
if (pack.more_results())
|
||||
{
|
||||
set_state(state_t::reading_first_subseq);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_state(state_t::complete);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Vendored
Executable
+123
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// Copyright (c) 2019-2023 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_EXECUTION_PROCESSOR_EXECUTION_STATE_IMPL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_EXECUTION_STATE_IMPL_HPP
|
||||
|
||||
#include <boost/mysql/diagnostics.hpp>
|
||||
#include <boost/mysql/error_code.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/metadata_collection_view.hpp>
|
||||
#include <boost/mysql/string_view.hpp>
|
||||
|
||||
#include <boost/mysql/detail/config.hpp>
|
||||
#include <boost/mysql/detail/execution_processor/execution_processor.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
class execution_state_impl final : public execution_processor
|
||||
{
|
||||
struct ok_data
|
||||
{
|
||||
bool has_value{false}; // The OK packet information is default constructed, or actual data?
|
||||
std::uint64_t affected_rows{}; // OK packet data
|
||||
std::uint64_t last_insert_id{}; // OK packet data
|
||||
std::uint16_t warnings{}; // OK packet data
|
||||
bool is_out_params{false}; // Does this resultset contain OUT param information?
|
||||
};
|
||||
|
||||
std::vector<metadata> meta_;
|
||||
ok_data eof_data_;
|
||||
std::vector<char> info_;
|
||||
|
||||
void on_new_resultset() noexcept
|
||||
{
|
||||
meta_.clear();
|
||||
eof_data_ = ok_data{};
|
||||
info_.clear();
|
||||
}
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_ok_packet_impl(const ok_view& pack);
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void reset_impl() noexcept override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_head_ok_packet_impl(const ok_view& pack, diagnostics&) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_num_meta_impl(std::size_t num_columns) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_meta_impl(const coldef_view&, bool, diagnostics&) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_impl(span<const std::uint8_t> msg, const output_ref&, std::vector<field_view>& fields)
|
||||
override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_ok_packet_impl(const ok_view& pack) override final;
|
||||
|
||||
void on_row_batch_start_impl() noexcept override final {}
|
||||
|
||||
void on_row_batch_finish_impl() noexcept override final {}
|
||||
|
||||
public:
|
||||
execution_state_impl() = default;
|
||||
|
||||
metadata_collection_view meta() const noexcept { return meta_; }
|
||||
|
||||
std::uint64_t get_affected_rows() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(eof_data_.has_value);
|
||||
return eof_data_.affected_rows;
|
||||
}
|
||||
|
||||
std::uint64_t get_last_insert_id() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(eof_data_.has_value);
|
||||
return eof_data_.last_insert_id;
|
||||
}
|
||||
|
||||
unsigned get_warning_count() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(eof_data_.has_value);
|
||||
return eof_data_.warnings;
|
||||
}
|
||||
|
||||
string_view get_info() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(eof_data_.has_value);
|
||||
return string_view(info_.data(), info_.size());
|
||||
}
|
||||
|
||||
bool get_is_out_params() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(eof_data_.has_value);
|
||||
return eof_data_.is_out_params;
|
||||
}
|
||||
|
||||
execution_state_impl& get_interface() noexcept { return *this; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MYSQL_HEADER_ONLY
|
||||
#include <boost/mysql/impl/execution_state_impl.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
//
|
||||
// Copyright (c) 2019-2023 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_EXECUTION_PROCESSOR_RESULTS_IMPL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_RESULTS_IMPL_HPP
|
||||
|
||||
#include <boost/mysql/diagnostics.hpp>
|
||||
#include <boost/mysql/error_code.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/metadata_collection_view.hpp>
|
||||
#include <boost/mysql/rows_view.hpp>
|
||||
#include <boost/mysql/string_view.hpp>
|
||||
|
||||
#include <boost/mysql/detail/config.hpp>
|
||||
#include <boost/mysql/detail/execution_processor/execution_processor.hpp>
|
||||
#include <boost/mysql/detail/row_impl.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
struct per_resultset_data
|
||||
{
|
||||
std::size_t num_columns{}; // Number of columns this resultset has
|
||||
std::size_t meta_offset{}; // Offset into the vector of metadata
|
||||
std::size_t field_offset; // Offset into the vector of fields (append mode only)
|
||||
std::size_t num_rows{}; // Number of rows this resultset has (append mode only)
|
||||
std::uint64_t affected_rows{}; // OK packet data
|
||||
std::uint64_t last_insert_id{}; // OK packet data
|
||||
std::uint16_t warnings{}; // OK packet data
|
||||
std::size_t info_offset{}; // Offset into the vector of info characters
|
||||
std::size_t info_size{}; // Number of characters that this resultset's info string has
|
||||
bool has_ok_packet_data{false}; // The OK packet information is default constructed, or actual data?
|
||||
bool is_out_params{false}; // Does this resultset contain OUT param information?
|
||||
};
|
||||
|
||||
// A container similar to a vector with SBO. To avoid depending on Boost.Container
|
||||
class resultset_container
|
||||
{
|
||||
bool first_has_data_{false};
|
||||
per_resultset_data first_;
|
||||
std::vector<per_resultset_data> rest_;
|
||||
|
||||
public:
|
||||
resultset_container() = default;
|
||||
std::size_t size() const noexcept { return !first_has_data_ ? 0 : rest_.size() + 1; }
|
||||
bool empty() const noexcept { return !first_has_data_; }
|
||||
void clear() noexcept
|
||||
{
|
||||
first_has_data_ = false;
|
||||
rest_.clear();
|
||||
}
|
||||
per_resultset_data& operator[](std::size_t i) noexcept
|
||||
{
|
||||
return const_cast<per_resultset_data&>(const_cast<const resultset_container&>(*this)[i]);
|
||||
}
|
||||
const per_resultset_data& operator[](std::size_t i) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(i < size());
|
||||
return i == 0 ? first_ : rest_[i - 1];
|
||||
}
|
||||
per_resultset_data& back() noexcept
|
||||
{
|
||||
return const_cast<per_resultset_data&>(const_cast<const resultset_container&>(*this).back());
|
||||
}
|
||||
const per_resultset_data& back() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(first_has_data_);
|
||||
return rest_.empty() ? first_ : rest_.back();
|
||||
}
|
||||
BOOST_MYSQL_DECL per_resultset_data& emplace_back();
|
||||
};
|
||||
|
||||
// Rows for all resultsets are stored in a single rows_impl object.
|
||||
// - When a row batch is started, we record how many fields we had before the batch.
|
||||
// - When rows are read, fields are allocated in the rows_impl object, then deserialized against
|
||||
// the allocated storage. At this point, strings/blobs point into the connection read buffer.
|
||||
// - When a row batch is finished, we copy strings/blobs into the rows_impl, then transform them
|
||||
// into offsets to allow rows_impl to grow.
|
||||
// - When the final OK packet is received, offsets are transformed back into views.
|
||||
class results_impl final : public execution_processor
|
||||
{
|
||||
public:
|
||||
results_impl() = default;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
row_view get_out_params() const noexcept;
|
||||
|
||||
std::size_t num_resultsets() const noexcept { return per_result_.size(); }
|
||||
|
||||
rows_view get_rows(std::size_t index) const noexcept
|
||||
{
|
||||
const auto& resultset_data = per_result_[index];
|
||||
return access::construct<rows_view>(
|
||||
rows_.fields().data() + resultset_data.field_offset,
|
||||
resultset_data.num_rows * resultset_data.num_columns,
|
||||
resultset_data.num_columns
|
||||
);
|
||||
}
|
||||
|
||||
metadata_collection_view get_meta(std::size_t index) const noexcept
|
||||
{
|
||||
const auto& resultset_data = get_resultset(index);
|
||||
return metadata_collection_view(
|
||||
meta_.data() + resultset_data.meta_offset,
|
||||
resultset_data.num_columns
|
||||
);
|
||||
}
|
||||
|
||||
std::uint64_t get_affected_rows(std::size_t index) const noexcept
|
||||
{
|
||||
return get_resultset(index).affected_rows;
|
||||
}
|
||||
|
||||
std::uint64_t get_last_insert_id(std::size_t index) const noexcept
|
||||
{
|
||||
return get_resultset(index).last_insert_id;
|
||||
}
|
||||
|
||||
unsigned get_warning_count(std::size_t index) const noexcept { return get_resultset(index).warnings; }
|
||||
|
||||
string_view get_info(std::size_t index) const noexcept
|
||||
{
|
||||
const auto& resultset_data = get_resultset(index);
|
||||
return string_view(info_.data() + resultset_data.info_offset, resultset_data.info_size);
|
||||
}
|
||||
|
||||
bool get_is_out_params(std::size_t index) const noexcept { return get_resultset(index).is_out_params; }
|
||||
|
||||
results_impl& get_interface() noexcept { return *this; }
|
||||
|
||||
private:
|
||||
// Virtual impls
|
||||
BOOST_MYSQL_DECL
|
||||
void reset_impl() noexcept override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_num_meta_impl(std::size_t num_columns) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_head_ok_packet_impl(const ok_view& pack, diagnostics&) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_meta_impl(const coldef_view&, bool, diagnostics&) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_impl(span<const std::uint8_t> msg, const output_ref&, std::vector<field_view>&)
|
||||
override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_ok_packet_impl(const ok_view& pack) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_row_batch_start_impl() override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_row_batch_finish_impl() override final;
|
||||
|
||||
// Data
|
||||
std::vector<metadata> meta_;
|
||||
resultset_container per_result_;
|
||||
std::vector<char> info_;
|
||||
row_impl rows_;
|
||||
std::size_t num_fields_at_batch_start_{no_batch};
|
||||
|
||||
// Auxiliar
|
||||
static constexpr std::size_t no_batch = std::size_t(-1);
|
||||
|
||||
bool has_active_batch() const noexcept { return num_fields_at_batch_start_ != no_batch; }
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void finish_batch();
|
||||
|
||||
per_resultset_data& current_resultset() noexcept
|
||||
{
|
||||
BOOST_ASSERT(!per_result_.empty());
|
||||
return per_result_.back();
|
||||
}
|
||||
|
||||
const per_resultset_data& current_resultset() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(!per_result_.empty());
|
||||
return per_result_.back();
|
||||
}
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
per_resultset_data& add_resultset();
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_ok_packet_impl(const ok_view& pack);
|
||||
|
||||
const per_resultset_data& get_resultset(std::size_t index) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(index < per_result_.size());
|
||||
return per_result_[index];
|
||||
}
|
||||
|
||||
metadata_collection_view current_resultset_meta() const noexcept
|
||||
{
|
||||
return get_meta(per_result_.size() - 1);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MYSQL_HEADER_ONLY
|
||||
#include <boost/mysql/impl/results_impl.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
Executable
+295
@@ -0,0 +1,295 @@
|
||||
//
|
||||
// Copyright (c) 2019-2023 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_EXECUTION_PROCESSOR_STATIC_EXECUTION_STATE_IMPL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_STATIC_EXECUTION_STATE_IMPL_HPP
|
||||
|
||||
#include <boost/mysql/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MYSQL_CXX14
|
||||
|
||||
#include <boost/mysql/diagnostics.hpp>
|
||||
#include <boost/mysql/error_code.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/metadata_collection_view.hpp>
|
||||
#include <boost/mysql/string_view.hpp>
|
||||
|
||||
#include <boost/mysql/detail/execution_processor/execution_processor.hpp>
|
||||
#include <boost/mysql/detail/typing/get_type_index.hpp>
|
||||
#include <boost/mysql/detail/typing/row_traits.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
using execst_parse_fn_t =
|
||||
error_code (*)(span<const std::size_t> pos_map, span<const field_view> from, const output_ref& ref);
|
||||
|
||||
struct execst_resultset_descriptor
|
||||
{
|
||||
std::size_t num_columns;
|
||||
name_table_t name_table;
|
||||
meta_check_fn_t meta_check;
|
||||
execst_parse_fn_t parse_fn;
|
||||
std::size_t type_index;
|
||||
};
|
||||
|
||||
class execst_external_data
|
||||
{
|
||||
public:
|
||||
struct ptr_data
|
||||
{
|
||||
std::size_t* pos_map;
|
||||
};
|
||||
|
||||
execst_external_data(span<const execst_resultset_descriptor> desc, ptr_data ptr) noexcept
|
||||
: desc_(desc), ptr_(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t num_resultsets() const noexcept { return desc_.size(); }
|
||||
std::size_t num_columns(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].num_columns;
|
||||
}
|
||||
name_table_t name_table(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].name_table;
|
||||
}
|
||||
meta_check_fn_t meta_check_fn(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].meta_check;
|
||||
}
|
||||
execst_parse_fn_t parse_fn(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].parse_fn;
|
||||
}
|
||||
std::size_t type_index(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].type_index;
|
||||
}
|
||||
span<std::size_t> pos_map(std::size_t idx) const noexcept
|
||||
{
|
||||
return span<std::size_t>(ptr_.pos_map, num_columns(idx));
|
||||
}
|
||||
|
||||
void set_pointers(ptr_data ptr) noexcept { ptr_ = ptr; }
|
||||
|
||||
private:
|
||||
span<const execst_resultset_descriptor> desc_;
|
||||
ptr_data ptr_;
|
||||
};
|
||||
|
||||
class static_execution_state_erased_impl final : public execution_processor
|
||||
{
|
||||
public:
|
||||
static_execution_state_erased_impl(execst_external_data ext) noexcept : ext_(ext) {}
|
||||
|
||||
execst_external_data& ext_data() noexcept { return ext_; }
|
||||
|
||||
metadata_collection_view meta() const noexcept { return meta_; }
|
||||
|
||||
std::uint64_t get_affected_rows() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ok_data_.has_value);
|
||||
return ok_data_.affected_rows;
|
||||
}
|
||||
|
||||
std::uint64_t get_last_insert_id() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ok_data_.has_value);
|
||||
return ok_data_.last_insert_id;
|
||||
}
|
||||
|
||||
unsigned get_warning_count() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ok_data_.has_value);
|
||||
return ok_data_.warnings;
|
||||
}
|
||||
|
||||
string_view get_info() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ok_data_.has_value);
|
||||
return string_view(info_.data(), info_.size());
|
||||
}
|
||||
|
||||
bool get_is_out_params() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ok_data_.has_value);
|
||||
return ok_data_.is_out_params;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data
|
||||
struct ok_packet_data
|
||||
{
|
||||
bool has_value{false}; // The OK packet information is default constructed, or actual data?
|
||||
std::uint64_t affected_rows{}; // OK packet data
|
||||
std::uint64_t last_insert_id{}; // OK packet data
|
||||
std::uint16_t warnings{}; // OK packet data
|
||||
bool is_out_params{false}; // Does this resultset contain OUT param information?
|
||||
};
|
||||
|
||||
execst_external_data ext_;
|
||||
std::size_t resultset_index_{};
|
||||
ok_packet_data ok_data_;
|
||||
std::vector<char> info_;
|
||||
std::vector<metadata> meta_;
|
||||
|
||||
// Virtual impls
|
||||
BOOST_MYSQL_DECL
|
||||
void reset_impl() noexcept override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_head_ok_packet_impl(const ok_view& pack, diagnostics& diag) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_num_meta_impl(std::size_t num_columns) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_meta_impl(const coldef_view& coldef, bool is_last, diagnostics& diag) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_impl(
|
||||
span<const std::uint8_t> msg,
|
||||
const output_ref& ref,
|
||||
std::vector<field_view>& fields
|
||||
) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_ok_packet_impl(const ok_view& pack) override final;
|
||||
|
||||
void on_row_batch_start_impl() noexcept override final {}
|
||||
|
||||
void on_row_batch_finish_impl() noexcept override final {}
|
||||
|
||||
// Auxiliar
|
||||
name_table_t current_name_table() const noexcept { return ext_.name_table(resultset_index_ - 1); }
|
||||
span<std::size_t> current_pos_map() noexcept { return ext_.pos_map(resultset_index_ - 1); }
|
||||
span<const std::size_t> current_pos_map() const noexcept { return ext_.pos_map(resultset_index_ - 1); }
|
||||
|
||||
error_code meta_check(diagnostics& diag) const
|
||||
{
|
||||
return ext_.meta_check_fn(resultset_index_ - 1)(current_pos_map(), meta_, diag);
|
||||
}
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_new_resultset() noexcept;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_ok_packet_impl(const ok_view& pack);
|
||||
};
|
||||
|
||||
template <class StaticRow>
|
||||
static error_code execst_parse_fn(
|
||||
span<const std::size_t> pos_map,
|
||||
span<const field_view> from,
|
||||
const output_ref& ref
|
||||
)
|
||||
{
|
||||
return parse(pos_map, from, ref.span_element<StaticRow>());
|
||||
}
|
||||
|
||||
template <class... StaticRow>
|
||||
constexpr std::array<execst_resultset_descriptor, sizeof...(StaticRow)> create_execst_resultset_descriptors()
|
||||
{
|
||||
return {{{
|
||||
get_row_size<StaticRow>(),
|
||||
get_row_name_table<StaticRow>(),
|
||||
&meta_check<StaticRow>,
|
||||
&execst_parse_fn<StaticRow>,
|
||||
get_type_index<StaticRow, StaticRow...>(),
|
||||
}...}};
|
||||
}
|
||||
|
||||
template <class... StaticRow>
|
||||
constexpr std::array<execst_resultset_descriptor, sizeof...(StaticRow)>
|
||||
execst_resultset_descriptor_table = create_execst_resultset_descriptors<StaticRow...>();
|
||||
|
||||
template <BOOST_MYSQL_STATIC_ROW... StaticRow>
|
||||
class static_execution_state_impl
|
||||
{
|
||||
// Storage for our data, which requires knowing the template args
|
||||
struct
|
||||
{
|
||||
std::array<std::size_t, max_num_columns<StaticRow...>> pos_map{};
|
||||
} data_;
|
||||
|
||||
// The type-erased impl, that will use pointers to the above storage
|
||||
static_execution_state_erased_impl impl_;
|
||||
|
||||
execst_external_data::ptr_data ptr_data() noexcept
|
||||
{
|
||||
return {
|
||||
data_.pos_map.data(),
|
||||
};
|
||||
}
|
||||
|
||||
void set_pointers() noexcept { impl_.ext_data().set_pointers(ptr_data()); }
|
||||
|
||||
public:
|
||||
static_execution_state_impl() noexcept
|
||||
: impl_({execst_resultset_descriptor_table<StaticRow...>, ptr_data()})
|
||||
{
|
||||
}
|
||||
|
||||
static_execution_state_impl(const static_execution_state_impl& rhs) : data_(rhs.data_), impl_(rhs.impl_)
|
||||
{
|
||||
set_pointers();
|
||||
}
|
||||
|
||||
static_execution_state_impl(static_execution_state_impl&& rhs) noexcept
|
||||
: data_(std::move(rhs.data_)), impl_(std::move(rhs.impl_))
|
||||
{
|
||||
set_pointers();
|
||||
}
|
||||
|
||||
static_execution_state_impl& operator=(const static_execution_state_impl& rhs)
|
||||
{
|
||||
data_ = rhs.data_;
|
||||
impl_ = rhs.impl_;
|
||||
set_pointers();
|
||||
return *this;
|
||||
}
|
||||
|
||||
static_execution_state_impl& operator=(static_execution_state_impl&& rhs)
|
||||
{
|
||||
data_ = std::move(rhs.data_);
|
||||
impl_ = std::move(rhs.impl_);
|
||||
set_pointers();
|
||||
return *this;
|
||||
}
|
||||
|
||||
~static_execution_state_impl() = default;
|
||||
|
||||
const static_execution_state_erased_impl& get_interface() const noexcept { return impl_; }
|
||||
static_execution_state_erased_impl& get_interface() noexcept { return impl_; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MYSQL_HEADER_ONLY
|
||||
#include <boost/mysql/impl/static_execution_state_impl.ipp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MYSQL_CXX14
|
||||
|
||||
#endif
|
||||
Vendored
Executable
+349
@@ -0,0 +1,349 @@
|
||||
//
|
||||
// Copyright (c) 2019-2023 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_EXECUTION_PROCESSOR_STATIC_RESULTS_IMPL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_STATIC_RESULTS_IMPL_HPP
|
||||
|
||||
#include <boost/mysql/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MYSQL_CXX14
|
||||
|
||||
#include <boost/mysql/diagnostics.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/metadata_collection_view.hpp>
|
||||
#include <boost/mysql/string_view.hpp>
|
||||
|
||||
#include <boost/mysql/detail/execution_processor/execution_processor.hpp>
|
||||
#include <boost/mysql/detail/typing/readable_field_traits.hpp>
|
||||
#include <boost/mysql/detail/typing/row_traits.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
using results_reset_fn_t = void (*)(void*);
|
||||
using results_parse_fn_t =
|
||||
error_code (*)(span<const std::size_t> pos_map, span<const field_view> from, void* to);
|
||||
|
||||
struct results_resultset_descriptor
|
||||
{
|
||||
std::size_t num_columns;
|
||||
name_table_t name_table;
|
||||
meta_check_fn_t meta_check;
|
||||
results_parse_fn_t parse_fn;
|
||||
};
|
||||
|
||||
struct static_per_resultset_data
|
||||
{
|
||||
std::size_t meta_offset{};
|
||||
std::size_t meta_size{};
|
||||
std::size_t info_offset{};
|
||||
std::size_t info_size{};
|
||||
bool has_ok_packet_data{false}; // The OK packet information is default constructed, or actual data?
|
||||
std::uint64_t affected_rows{}; // OK packet data
|
||||
std::uint64_t last_insert_id{}; // OK packet data
|
||||
std::uint16_t warnings{}; // OK packet data
|
||||
bool is_out_params{false}; // Does this resultset contain OUT param information?
|
||||
};
|
||||
|
||||
class results_external_data
|
||||
{
|
||||
public:
|
||||
struct ptr_data
|
||||
{
|
||||
void* rows;
|
||||
std::size_t* pos_map;
|
||||
static_per_resultset_data* per_resultset;
|
||||
};
|
||||
|
||||
results_external_data(
|
||||
span<const results_resultset_descriptor> desc,
|
||||
results_reset_fn_t reset,
|
||||
ptr_data ptr
|
||||
) noexcept
|
||||
: desc_(desc), reset_(reset), ptr_(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
void set_pointers(ptr_data ptr) noexcept { ptr_ = ptr; }
|
||||
|
||||
std::size_t num_resultsets() const noexcept { return desc_.size(); }
|
||||
std::size_t num_columns(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].num_columns;
|
||||
}
|
||||
name_table_t name_table(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].name_table;
|
||||
}
|
||||
meta_check_fn_t meta_check_fn(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].meta_check;
|
||||
}
|
||||
results_parse_fn_t parse_fn(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return desc_[idx].parse_fn;
|
||||
}
|
||||
results_reset_fn_t reset_fn() const noexcept { return reset_; }
|
||||
void* rows() const noexcept { return ptr_.rows; }
|
||||
span<std::size_t> pos_map(std::size_t idx) const noexcept
|
||||
{
|
||||
return span<std::size_t>(ptr_.pos_map, num_columns(idx));
|
||||
}
|
||||
static_per_resultset_data& per_result(std::size_t idx) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(idx < num_resultsets());
|
||||
return ptr_.per_resultset[idx];
|
||||
}
|
||||
|
||||
private:
|
||||
span<const results_resultset_descriptor> desc_;
|
||||
results_reset_fn_t reset_;
|
||||
ptr_data ptr_;
|
||||
};
|
||||
|
||||
class static_results_erased_impl final : public execution_processor
|
||||
{
|
||||
public:
|
||||
static_results_erased_impl(results_external_data ext) noexcept : ext_(ext) {}
|
||||
|
||||
results_external_data& ext_data() noexcept { return ext_; }
|
||||
|
||||
metadata_collection_view get_meta(std::size_t index) const noexcept
|
||||
{
|
||||
const auto& resultset_data = ext_.per_result(index);
|
||||
return metadata_collection_view(meta_.data() + resultset_data.meta_offset, resultset_data.meta_size);
|
||||
}
|
||||
|
||||
std::uint64_t get_affected_rows(std::size_t index) const noexcept
|
||||
{
|
||||
return ext_.per_result(index).affected_rows;
|
||||
}
|
||||
|
||||
std::uint64_t get_last_insert_id(std::size_t index) const noexcept
|
||||
{
|
||||
return ext_.per_result(index).last_insert_id;
|
||||
}
|
||||
|
||||
unsigned get_warning_count(std::size_t index) const noexcept { return ext_.per_result(index).warnings; }
|
||||
|
||||
string_view get_info(std::size_t index) const noexcept
|
||||
{
|
||||
const auto& resultset_data = ext_.per_result(index);
|
||||
return string_view(info_.data() + resultset_data.info_offset, resultset_data.info_size);
|
||||
}
|
||||
|
||||
bool get_is_out_params(std::size_t index) const noexcept { return ext_.per_result(index).is_out_params; }
|
||||
|
||||
private:
|
||||
// Virtual implementations
|
||||
BOOST_MYSQL_DECL
|
||||
void reset_impl() noexcept override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_head_ok_packet_impl(const ok_view& pack, diagnostics& diag) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
void on_num_meta_impl(std::size_t num_columns) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_meta_impl(const coldef_view& coldef, bool is_last, diagnostics& diag) override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_impl(span<const std::uint8_t> msg, const output_ref&, std::vector<field_view>& fields)
|
||||
override final;
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_row_ok_packet_impl(const ok_view& pack) override final;
|
||||
|
||||
void on_row_batch_start_impl() override final {}
|
||||
void on_row_batch_finish_impl() override final {}
|
||||
|
||||
// Data
|
||||
results_external_data ext_;
|
||||
std::vector<metadata> meta_;
|
||||
std::vector<char> info_;
|
||||
std::size_t resultset_index_{0};
|
||||
|
||||
// Helpers
|
||||
span<std::size_t> current_pos_map() noexcept { return ext_.pos_map(resultset_index_ - 1); }
|
||||
span<const std::size_t> current_pos_map() const noexcept { return ext_.pos_map(resultset_index_ - 1); }
|
||||
name_table_t current_name_table() const noexcept { return ext_.name_table(resultset_index_ - 1); }
|
||||
static_per_resultset_data& current_resultset() noexcept { return ext_.per_result(resultset_index_ - 1); }
|
||||
metadata_collection_view current_resultset_meta() const noexcept
|
||||
{
|
||||
return get_meta(resultset_index_ - 1);
|
||||
}
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
static_per_resultset_data& add_resultset();
|
||||
|
||||
BOOST_MYSQL_DECL
|
||||
error_code on_ok_packet_impl(const ok_view& pack);
|
||||
|
||||
error_code meta_check(diagnostics& diag) const
|
||||
{
|
||||
return ext_.meta_check_fn(resultset_index_ - 1)(current_pos_map(), current_resultset_meta(), diag);
|
||||
}
|
||||
};
|
||||
|
||||
template <class... StaticRow>
|
||||
using results_rows_t = std::tuple<std::vector<StaticRow>...>;
|
||||
|
||||
template <class... StaticRow>
|
||||
struct results_fns
|
||||
{
|
||||
using rows_t = results_rows_t<StaticRow...>;
|
||||
|
||||
struct reset_fn
|
||||
{
|
||||
rows_t& obj;
|
||||
|
||||
template <std::size_t I>
|
||||
void operator()(boost::mp11::mp_size_t<I>) const noexcept
|
||||
{
|
||||
std::get<I>(obj).clear();
|
||||
}
|
||||
};
|
||||
|
||||
static void reset(void* rows_ptr) noexcept
|
||||
{
|
||||
auto& rows = *static_cast<rows_t*>(rows_ptr);
|
||||
boost::mp11::mp_for_each<boost::mp11::mp_iota_c<sizeof...(StaticRow)>>(reset_fn{rows});
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
static error_code do_parse(span<const std::size_t> pos_map, span<const field_view> from, void* to)
|
||||
{
|
||||
auto& v = std::get<I>(*static_cast<rows_t*>(to));
|
||||
v.emplace_back();
|
||||
return parse(pos_map, from, v.back());
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
static constexpr results_resultset_descriptor create_descriptor()
|
||||
{
|
||||
using T = mp11::mp_at_c<mp11::mp_list<StaticRow...>, I>;
|
||||
return {
|
||||
get_row_size<T>(),
|
||||
get_row_name_table<T>(),
|
||||
&meta_check<T>,
|
||||
&do_parse<I>,
|
||||
};
|
||||
}
|
||||
|
||||
template <std::size_t... I>
|
||||
static constexpr std::array<results_resultset_descriptor, sizeof...(StaticRow)> create_descriptors(mp11::index_sequence<
|
||||
I...>)
|
||||
{
|
||||
return {{create_descriptor<I>()...}};
|
||||
}
|
||||
};
|
||||
|
||||
template <class... StaticRow>
|
||||
constexpr std::array<results_resultset_descriptor, sizeof...(StaticRow)>
|
||||
results_resultset_descriptor_table = results_fns<StaticRow...>::create_descriptors(
|
||||
mp11::make_index_sequence<sizeof...(StaticRow)>()
|
||||
);
|
||||
|
||||
template <BOOST_MYSQL_STATIC_ROW... StaticRow>
|
||||
class static_results_impl
|
||||
{
|
||||
// Data that requires knowing template params
|
||||
struct
|
||||
{
|
||||
results_rows_t<StaticRow...> rows;
|
||||
std::array<std::size_t, max_num_columns<StaticRow...>> pos_map{};
|
||||
std::array<static_per_resultset_data, sizeof...(StaticRow)> per_resultset{};
|
||||
} data_;
|
||||
|
||||
// The type-erased impl, that will use pointers to the above storage
|
||||
static_results_erased_impl impl_;
|
||||
|
||||
results_external_data::ptr_data ptr_data() noexcept
|
||||
{
|
||||
return {
|
||||
&data_.rows,
|
||||
data_.pos_map.data(),
|
||||
data_.per_resultset.data(),
|
||||
};
|
||||
}
|
||||
|
||||
void set_pointers() noexcept { impl_.ext_data().set_pointers(ptr_data()); }
|
||||
|
||||
public:
|
||||
static_results_impl() noexcept
|
||||
: impl_(results_external_data(
|
||||
results_resultset_descriptor_table<StaticRow...>,
|
||||
&results_fns<StaticRow...>::reset,
|
||||
ptr_data()
|
||||
))
|
||||
{
|
||||
}
|
||||
|
||||
static_results_impl(const static_results_impl& rhs) : data_(rhs.data_), impl_(rhs.impl_)
|
||||
{
|
||||
set_pointers();
|
||||
}
|
||||
|
||||
static_results_impl(static_results_impl&& rhs) noexcept
|
||||
: data_(std::move(rhs.data_)), impl_(std::move(rhs.impl_))
|
||||
{
|
||||
set_pointers();
|
||||
}
|
||||
|
||||
static_results_impl& operator=(const static_results_impl& rhs)
|
||||
{
|
||||
data_ = rhs.data_;
|
||||
impl_ = rhs.impl_;
|
||||
set_pointers();
|
||||
return *this;
|
||||
}
|
||||
|
||||
static_results_impl& operator=(static_results_impl&& rhs)
|
||||
{
|
||||
data_ = std::move(rhs.data_);
|
||||
impl_ = std::move(rhs.impl_);
|
||||
set_pointers();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// User facing
|
||||
template <std::size_t I>
|
||||
boost::span<const typename std::tuple_element<I, std::tuple<StaticRow...>>::type> get_rows(
|
||||
) const noexcept
|
||||
{
|
||||
return std::get<I>(data_.rows);
|
||||
}
|
||||
|
||||
const static_results_erased_impl& get_interface() const noexcept { return impl_; }
|
||||
static_results_erased_impl& get_interface() noexcept { return impl_; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MYSQL_HEADER_ONLY
|
||||
#include <boost/mysql/impl/static_results_impl.ipp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MYSQL_CXX14
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user