Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:48:59

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_IMPL_FIELD_VIEW_HPP
0009 #define BOOST_MYSQL_IMPL_FIELD_VIEW_HPP
0010 
0011 #pragma once
0012 
0013 #include <boost/mysql/bad_field_access.hpp>
0014 #include <boost/mysql/field_view.hpp>
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/throw_exception.hpp>
0018 
0019 #include <cstring>
0020 #include <limits>
0021 
0022 namespace boost {
0023 namespace mysql {
0024 namespace detail {
0025 
0026 inline bool blobs_equal(blob_view b1, blob_view b2)
0027 {
0028     if (b1.size() != b2.size())
0029         return false;
0030     return b1.empty() || std::memcmp(b1.data(), b2.data(), b2.size()) == 0;
0031 }
0032 
0033 }  // namespace detail
0034 }  // namespace mysql
0035 }  // namespace boost
0036 
0037 BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::field_view::kind() const noexcept
0038 {
0039     switch (impl_.ikind)
0040     {
0041     case internal_kind::null: return field_kind::null;
0042     case internal_kind::int64: return field_kind::int64;
0043     case internal_kind::uint64: return field_kind::uint64;
0044     case internal_kind::string: return field_kind::string;
0045     case internal_kind::blob: return field_kind::blob;
0046     case internal_kind::float_: return field_kind::float_;
0047     case internal_kind::double_: return field_kind::double_;
0048     case internal_kind::date: return field_kind::date;
0049     case internal_kind::datetime: return field_kind::datetime;
0050     case internal_kind::time: return field_kind::time;
0051     case internal_kind::field_ptr: return impl_.repr.field_ptr->kind();
0052     // sv_offset values must be converted via offset_to_string_view before calling any other fn
0053     default: return field_kind::null;
0054     }
0055 }
0056 
0057 BOOST_CXX14_CONSTEXPR std::int64_t boost::mysql::field_view::as_int64() const
0058 {
0059     if (is_field_ptr())
0060         return impl_.repr.field_ptr->as<std::int64_t>();
0061     check_kind(internal_kind::int64);
0062     return impl_.repr.int64;
0063 }
0064 
0065 BOOST_CXX14_CONSTEXPR std::uint64_t boost::mysql::field_view::as_uint64() const
0066 {
0067     if (is_field_ptr())
0068         return impl_.repr.field_ptr->as<std::uint64_t>();
0069     check_kind(internal_kind::uint64);
0070     return impl_.repr.uint64;
0071 }
0072 
0073 BOOST_CXX14_CONSTEXPR boost::mysql::string_view boost::mysql::field_view::as_string() const
0074 {
0075     if (is_field_ptr())
0076         return impl_.repr.field_ptr->as<std::string>();
0077     check_kind(internal_kind::string);
0078     return impl_.repr.string;
0079 }
0080 
0081 BOOST_CXX14_CONSTEXPR boost::mysql::blob_view boost::mysql::field_view::as_blob() const
0082 {
0083     if (is_field_ptr())
0084         return impl_.repr.field_ptr->as<blob>();
0085     check_kind(internal_kind::blob);
0086     return impl_.repr.blob;
0087 }
0088 
0089 BOOST_CXX14_CONSTEXPR float boost::mysql::field_view::as_float() const
0090 {
0091     if (is_field_ptr())
0092         return impl_.repr.field_ptr->as<float>();
0093     check_kind(internal_kind::float_);
0094     return impl_.repr.float_;
0095 }
0096 
0097 BOOST_CXX14_CONSTEXPR double boost::mysql::field_view::as_double() const
0098 {
0099     if (is_field_ptr())
0100         return impl_.repr.field_ptr->as<double>();
0101     check_kind(internal_kind::double_);
0102     return impl_.repr.double_;
0103 }
0104 
0105 BOOST_CXX14_CONSTEXPR boost::mysql::date boost::mysql::field_view::as_date() const
0106 {
0107     if (is_field_ptr())
0108         return impl_.repr.field_ptr->as<date>();
0109     check_kind(internal_kind::date);
0110     return impl_.repr.date_;
0111 }
0112 
0113 BOOST_CXX14_CONSTEXPR boost::mysql::datetime boost::mysql::field_view::as_datetime() const
0114 {
0115     if (is_field_ptr())
0116         return impl_.repr.field_ptr->as<datetime>();
0117     check_kind(internal_kind::datetime);
0118     return impl_.repr.datetime_;
0119 }
0120 
0121 BOOST_CXX14_CONSTEXPR boost::mysql::time boost::mysql::field_view::as_time() const
0122 {
0123     if (is_field_ptr())
0124         return impl_.repr.field_ptr->as<time>();
0125     check_kind(internal_kind::time);
0126     return impl_.repr.time_;
0127 }
0128 
0129 BOOST_CXX14_CONSTEXPR void boost::mysql::field_view::check_kind(internal_kind expected) const
0130 {
0131     if (impl_.ikind != expected)
0132         BOOST_THROW_EXCEPTION(bad_field_access());
0133 }
0134 
0135 BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(const field_view& rhs) const noexcept
0136 {
0137     // Make operator== work for types not representable by field_kind
0138     if (impl_.ikind == internal_kind::sv_offset_string || impl_.ikind == internal_kind::sv_offset_blob)
0139     {
0140         return rhs.impl_.ikind == impl_.ikind && impl_.repr.sv_offset_ == rhs.impl_.repr.sv_offset_;
0141     }
0142 
0143     auto k = kind(), rhs_k = rhs.kind();
0144     switch (k)
0145     {
0146     case field_kind::null: return rhs_k == field_kind::null;
0147     case field_kind::int64:
0148         if (rhs_k == field_kind::int64)
0149             return get_int64() == rhs.get_int64();
0150         else if (rhs_k == field_kind::uint64)
0151         {
0152             std::int64_t this_val = get_int64();
0153             if (this_val < 0)
0154                 return false;
0155             else
0156                 return static_cast<std::uint64_t>(this_val) == rhs.get_uint64();
0157         }
0158         else
0159             return false;
0160     case field_kind::uint64:
0161         if (rhs_k == field_kind::uint64)
0162             return get_uint64() == rhs.get_uint64();
0163         else if (rhs_k == field_kind::int64)
0164         {
0165             std::int64_t rhs_val = rhs.get_int64();
0166             if (rhs_val < 0)
0167                 return false;
0168             else
0169                 return static_cast<std::uint64_t>(rhs_val) == get_uint64();
0170         }
0171         else
0172             return false;
0173     case field_kind::string: return rhs_k == field_kind::string && get_string() == rhs.get_string();
0174     case field_kind::blob:
0175         return rhs_k == field_kind::blob && detail::blobs_equal(get_blob(), rhs.get_blob());
0176     case field_kind::float_: return rhs_k == field_kind::float_ && get_float() == rhs.get_float();
0177     case field_kind::double_: return rhs_k == field_kind::double_ && get_double() == rhs.get_double();
0178     case field_kind::date: return rhs_k == field_kind::date && get_date() == rhs.get_date();
0179     case field_kind::datetime: return rhs_k == field_kind::datetime && get_datetime() == rhs.get_datetime();
0180     case field_kind::time: return rhs_k == field_kind::time && get_time() == rhs.get_time();
0181     default: BOOST_ASSERT(false); return false;
0182     }
0183 }
0184 
0185 #endif