field_impl.hpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //
  2. // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MYSQL_DETAIL_FIELD_IMPL_HPP
  8. #define BOOST_MYSQL_DETAIL_FIELD_IMPL_HPP
  9. #include <boost/mysql/bad_field_access.hpp>
  10. #include <boost/mysql/blob.hpp>
  11. #include <boost/mysql/date.hpp>
  12. #include <boost/mysql/datetime.hpp>
  13. #include <boost/mysql/field_kind.hpp>
  14. #include <boost/mysql/time.hpp>
  15. #include <boost/mp11/algorithm.hpp>
  16. #include <boost/throw_exception.hpp>
  17. #include <boost/variant2/variant.hpp>
  18. #include <string>
  19. #include <type_traits>
  20. namespace boost {
  21. namespace mysql {
  22. namespace detail {
  23. // Breaks a circular dependency between field_view and field
  24. struct field_impl
  25. {
  26. using null_t = boost::variant2::monostate;
  27. using variant_type = boost::variant2::variant<
  28. null_t, // Any of the below when the value is NULL
  29. std::int64_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
  30. std::uint64_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, YEAR, BIT
  31. std::string, // CHAR, VARCHAR, TEXT (all sizes), , ENUM,
  32. // SET, DECIMAL
  33. blob, // BINARY, VARBINARY, BLOB (all sizes), GEOMETRY
  34. float, // FLOAT
  35. double, // DOUBLE
  36. date, // DATE
  37. datetime, // DATETIME, TIMESTAMP
  38. time // TIME
  39. >;
  40. variant_type data;
  41. field_impl() = default;
  42. template <typename... Args>
  43. field_impl(Args&&... args) noexcept(std::is_nothrow_constructible<variant_type, Args...>::value)
  44. : data(std::forward<Args>(args)...)
  45. {
  46. }
  47. field_kind kind() const noexcept { return static_cast<field_kind>(data.index()); }
  48. template <typename T>
  49. const T& as() const
  50. {
  51. const T* res = boost::variant2::get_if<T>(&data);
  52. if (!res)
  53. BOOST_THROW_EXCEPTION(bad_field_access());
  54. return *res;
  55. }
  56. template <typename T>
  57. T& as()
  58. {
  59. T* res = boost::variant2::get_if<T>(&data);
  60. if (!res)
  61. BOOST_THROW_EXCEPTION(bad_field_access());
  62. return *res;
  63. }
  64. template <typename T>
  65. const T& get() const noexcept
  66. {
  67. constexpr auto I = mp11::mp_find<variant_type, T>::value;
  68. return boost::variant2::unsafe_get<I>(data);
  69. }
  70. template <typename T>
  71. T& get() noexcept
  72. {
  73. constexpr auto I = mp11::mp_find<variant_type, T>::value;
  74. return boost::variant2::unsafe_get<I>(data);
  75. }
  76. };
  77. } // namespace detail
  78. } // namespace mysql
  79. } // namespace boost
  80. #endif