// // 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 // 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 #include #include #include #include #include #include #include #if BOOST_PFR_CORE_NAME_ENABLED #include #include #include #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 constexpr bool is_pfr_reflectable() noexcept { return std::is_class::value && !std::is_const::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 #endif ; } template using pfr_fields_t = decltype(pfr::structure_to_tuple(std::declval())); #if BOOST_PFR_CORE_NAME_ENABLED // PFR field names use std::string_view template constexpr std::array to_name_table_storage(std::array input) noexcept { std::array 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 to_name_table_storage(std::array) noexcept { return {}; } template constexpr inline auto pfr_names_storage = to_name_table_storage(pfr::names_as_array()); template class row_traits, false> { static_assert( is_pfr_reflectable(), "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; static constexpr name_table_t name_table() noexcept { return pfr_names_storage; } template static void for_each_member(T& to, F&& function) { pfr::for_each_field(to, std::forward(function)); } }; #endif template class row_traits, false> { static_assert( is_pfr_reflectable(), "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; static constexpr name_table_t name_table() noexcept { return {}; } template static void for_each_member(T& to, F&& function) { pfr::for_each_field(to, std::forward(function)); } }; } // namespace detail } // namespace mysql } // namespace boost #if defined(BOOST_MSVC) && BOOST_MSVC < 1920 #pragma warning(pop) #endif #endif