// // 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 BHO_MYSQL_DETAIL_TYPING_ROW_TRAITS_HPP #define BHO_MYSQL_DETAIL_TYPING_ROW_TRAITS_HPP #include #ifdef BHO_MYSQL_CXX14 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace bho { namespace mysql { namespace detail { // Helpers to check that all the fields satisfy ReadableField // and produce meaningful error messages, with the offending field type, at least // Workaround clang 3.6 not liking generic lambdas in the below constexpr function struct readable_field_checker { template constexpr void operator()(TypeIdentity) const noexcept { using T = typename TypeIdentity::type; static_assert( is_readable_field::value, "You're trying to use an unsupported field type in a row type. Review your row type definitions." ); } }; template static constexpr bool check_readable_field() noexcept { mp11::mp_for_each(readable_field_checker{}); return true; } // Workaround std::array::data not being constexpr in C++14 template struct array_wrapper { T data_[N]; constexpr bho::span span() const noexcept { return bho::span(data_); } }; template struct array_wrapper { struct { } data_; // allow empty brace initialization constexpr bho::span span() const noexcept { return bho::span(); } }; // Workaround for char_traits::length not being constexpr in C++14 // Only used to retrieve Describe member name lengths constexpr std::size_t get_length(const char* s) noexcept { const char* p = s; while (*p) ++p; return p - s; } // Helpers class parse_functor { span pos_map_; span fields_; std::size_t index_{}; error_code ec_; public: parse_functor(span pos_map, span fields) noexcept : pos_map_(pos_map), fields_(fields) { } template void operator()(ReadableField& output) { auto ec = readable_field_traits::parse( map_field_view(pos_map_, index_++, fields_), output ); if (!ec_) ec_ = ec; } error_code error() const noexcept { return ec_; } }; // Base template template ::value> class row_traits; // Describe structs template using row_members = bho::describe:: describe_members; template constexpr string_view get_member_name(MemberDescriptor d) noexcept { return string_view(d.name, get_length(d.name)); } template