123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- //
- // 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
|