Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:38

0001 //
0002 // Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_MYSQL_DETAIL_TYPING_POS_MAP_HPP
0009 #define BOOST_MYSQL_DETAIL_TYPING_POS_MAP_HPP
0010 
0011 #include <boost/mysql/field_view.hpp>
0012 #include <boost/mysql/metadata.hpp>
0013 #include <boost/mysql/metadata_collection_view.hpp>
0014 #include <boost/mysql/string_view.hpp>
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/core/span.hpp>
0018 
0019 #include <cstddef>
0020 
0021 namespace boost {
0022 namespace mysql {
0023 namespace detail {
0024 
0025 // These functions map C++ type positions to positions to positions in the DB query
0026 
0027 constexpr std::size_t pos_absent = static_cast<std::size_t>(-1);
0028 using name_table_t = boost::span<const string_view>;
0029 
0030 inline bool has_field_names(name_table_t name_table) noexcept { return !name_table.empty(); }
0031 
0032 inline void pos_map_reset(span<std::size_t> self) noexcept
0033 {
0034     for (std::size_t i = 0; i < self.size(); ++i)
0035         self.data()[i] = pos_absent;
0036 }
0037 
0038 inline void pos_map_add_field(
0039     span<std::size_t> self,
0040     name_table_t name_table,
0041     std::size_t db_index,
0042     string_view field_name
0043 ) noexcept
0044 {
0045     if (has_field_names(name_table))
0046     {
0047         BOOST_ASSERT(self.size() == name_table.size());
0048 
0049         // We're mapping fields by name. Try to find where in our target struct
0050         // is the current field located
0051         auto it = std::find(name_table.begin(), name_table.end(), field_name);
0052         if (it != name_table.end())
0053         {
0054             std::size_t cpp_index = it - name_table.begin();
0055             self[cpp_index] = db_index;
0056         }
0057     }
0058     else
0059     {
0060         // We're mapping by position. Any extra trailing fields are discarded
0061         if (db_index < self.size())
0062         {
0063             self[db_index] = db_index;
0064         }
0065     }
0066 }
0067 
0068 inline field_view map_field_view(
0069     span<const std::size_t> self,
0070     std::size_t cpp_index,
0071     span<const field_view> array
0072 ) noexcept
0073 {
0074     BOOST_ASSERT(cpp_index < self.size());
0075     return array[self[cpp_index]];
0076 }
0077 
0078 inline const metadata& map_metadata(
0079     span<const std::size_t> self,
0080     std::size_t cpp_index,
0081     metadata_collection_view meta
0082 ) noexcept
0083 {
0084     BOOST_ASSERT(cpp_index < self.size());
0085     return meta[self[cpp_index]];
0086 }
0087 
0088 }  // namespace detail
0089 }  // namespace mysql
0090 }  // namespace boost
0091 
0092 #endif