144 lines
3.6 KiB
C++
144 lines
3.6 KiB
C++
|
//
|
||
|
// Copyright (c) 2019-2024 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_IMPL_PFR_HPP
|
||
|
#define BOOST_MYSQL_IMPL_PFR_HPP
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <boost/config.hpp>
|
||
|
|
||
|
// Silence PFR warnings caused by https://github.com/boostorg/pfr/issues/166
|
||
|
// Only affecting gcc-11+, and caused during the inclusion of the library
|
||
|
#if BOOST_GCC >= 110000
|
||
|
#pragma GCC diagnostic push
|
||
|
#pragma GCC diagnostic ignored "-Wpragmas"
|
||
|
#endif
|
||
|
|
||
|
// Silence MSVC 14.1 warnings caused by https://github.com/boostorg/pfr/issues/167
|
||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1920
|
||
|
#pragma warning(push)
|
||
|
#pragma warning(disable : 4100)
|
||
|
#endif
|
||
|
|
||
|
#include <boost/mysql/pfr.hpp>
|
||
|
#include <boost/mysql/string_view.hpp>
|
||
|
|
||
|
#include <boost/mysql/detail/typing/row_traits.hpp>
|
||
|
|
||
|
#include <boost/pfr/core.hpp>
|
||
|
#include <boost/pfr/core_name.hpp>
|
||
|
#include <boost/pfr/traits.hpp>
|
||
|
|
||
|
#include <type_traits>
|
||
|
#include <utility>
|
||
|
|
||
|
#if BOOST_PFR_CORE_NAME_ENABLED
|
||
|
#include <array>
|
||
|
#include <cstddef>
|
||
|
#include <string_view>
|
||
|
#endif
|
||
|
|
||
|
#if BOOST_GCC >= 110000
|
||
|
#pragma GCC diagnostic pop
|
||
|
#endif
|
||
|
|
||
|
namespace boost {
|
||
|
namespace mysql {
|
||
|
namespace detail {
|
||
|
|
||
|
// Not all types reflected by PFR are acceptable for us - this function performs this checking
|
||
|
template <class T>
|
||
|
constexpr bool is_pfr_reflectable() noexcept
|
||
|
{
|
||
|
return std::is_class<T>::value && !std::is_const<T>::value
|
||
|
// is_implicitly_reflectable_v returns always false when implicit reflection
|
||
|
// (which requires structured bindings and C++17) is not available
|
||
|
#if BOOST_PFR_ENABLE_IMPLICIT_REFLECTION
|
||
|
&& pfr::is_implicitly_reflectable_v<T, struct mysql_tag>
|
||
|
#endif
|
||
|
;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
using pfr_fields_t = decltype(pfr::structure_to_tuple(std::declval<const T&>()));
|
||
|
|
||
|
#if BOOST_PFR_CORE_NAME_ENABLED
|
||
|
|
||
|
// PFR field names use std::string_view
|
||
|
template <std::size_t N>
|
||
|
constexpr std::array<string_view, N> to_name_table_storage(std::array<std::string_view, N> input) noexcept
|
||
|
{
|
||
|
std::array<string_view, N> res;
|
||
|
for (std::size_t i = 0; i < N; ++i)
|
||
|
res[i] = input[i];
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
// Workaround for https://github.com/boostorg/pfr/issues/165
|
||
|
constexpr std::array<string_view, 0u> to_name_table_storage(std::array<std::nullptr_t, 0u>) noexcept
|
||
|
{
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
constexpr inline auto pfr_names_storage = to_name_table_storage(pfr::names_as_array<T>());
|
||
|
|
||
|
template <class T>
|
||
|
class row_traits<pfr_by_name<T>, false>
|
||
|
{
|
||
|
static_assert(
|
||
|
is_pfr_reflectable<T>(),
|
||
|
"T needs to be a non-const object type that supports PFR reflection"
|
||
|
);
|
||
|
|
||
|
public:
|
||
|
using underlying_row_type = T;
|
||
|
using field_types = pfr_fields_t<T>;
|
||
|
|
||
|
static constexpr name_table_t name_table() noexcept { return pfr_names_storage<T>; }
|
||
|
|
||
|
template <class F>
|
||
|
static void for_each_member(T& to, F&& function)
|
||
|
{
|
||
|
pfr::for_each_field(to, std::forward<F>(function));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
template <class T>
|
||
|
class row_traits<pfr_by_position<T>, false>
|
||
|
{
|
||
|
static_assert(
|
||
|
is_pfr_reflectable<T>(),
|
||
|
"T needs to be a non-const object type that supports PFR reflection"
|
||
|
);
|
||
|
|
||
|
public:
|
||
|
using underlying_row_type = T;
|
||
|
using field_types = pfr_fields_t<T>;
|
||
|
|
||
|
static constexpr name_table_t name_table() noexcept { return {}; }
|
||
|
|
||
|
template <class F>
|
||
|
static void for_each_member(T& to, F&& function)
|
||
|
{
|
||
|
pfr::for_each_field(to, std::forward<F>(function));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace detail
|
||
|
} // namespace mysql
|
||
|
} // namespace boost
|
||
|
|
||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1920
|
||
|
#pragma warning(pop)
|
||
|
#endif
|
||
|
|
||
|
#endif
|