// // Copyright (c) 2019-2025 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 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 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; } template constexpr inline std::size_t pfr_row_size_v = mp11::mp_size>::value; template constexpr std::array> create_pfr_name_table() noexcept { // Some MSVC compilers have trouble with pfr::names_as_array() when // the row type is empty if constexpr (pfr_row_size_v == 0u) { return {}; } else { return to_name_table_storage(pfr::names_as_array()); } } template constexpr inline auto pfr_names_storage = create_pfr_name_table(); 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