writable_field_traits.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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_WRITABLE_FIELD_TRAITS_HPP
  8. #define BOOST_MYSQL_DETAIL_WRITABLE_FIELD_TRAITS_HPP
  9. #include <boost/mysql/field_view.hpp>
  10. #include <boost/mysql/detail/config.hpp>
  11. #include <type_traits>
  12. namespace boost {
  13. namespace mysql {
  14. namespace detail {
  15. template <class T, class En1 = void, class En2 = void>
  16. struct writable_field_traits
  17. {
  18. static constexpr bool is_supported = false;
  19. };
  20. template <>
  21. struct writable_field_traits<bool>
  22. {
  23. static constexpr bool is_supported = true;
  24. static field_view to_field(bool value) noexcept { return field_view(value ? 1 : 0); }
  25. };
  26. template <class T>
  27. struct writable_field_traits<
  28. T,
  29. typename std::enable_if<
  30. std::is_constructible<field_view, const T&>::value && std::is_object<T>::value>::type,
  31. void>
  32. {
  33. static constexpr bool is_supported = true;
  34. static field_view to_field(const T& value) noexcept { return field_view(value); }
  35. };
  36. // Optionals. To avoid dependencies, we use a "concept".
  37. // We consider a type an optional if has a `bool has_value() const` and
  38. // `const value_type& value() const`
  39. template <class T>
  40. struct writable_field_traits<
  41. T,
  42. void,
  43. typename std::enable_if<
  44. std::is_same<decltype(std::declval<const T&>().has_value()), bool>::value &&
  45. std::is_same<decltype(std::declval<const T&>().value()), const typename T::value_type&>::value>::type>
  46. {
  47. using value_traits = writable_field_traits<typename T::value_type>;
  48. static constexpr bool is_supported = value_traits::is_supported;
  49. static field_view to_field(const T& value) noexcept
  50. {
  51. return value.has_value() ? value_traits::to_field(value.value()) : field_view();
  52. }
  53. };
  54. template <class T>
  55. field_view to_field(const T& value) noexcept
  56. {
  57. return writable_field_traits<T>::to_field(value);
  58. }
  59. template <class T>
  60. struct is_writable_field : std::integral_constant<bool, writable_field_traits<T>::is_supported>
  61. {
  62. };
  63. #ifdef BOOST_MYSQL_HAS_CONCEPTS
  64. template <class T>
  65. concept writable_field = is_writable_field<T>::value;
  66. #define BOOST_MYSQL_WRITABLE_FIELD ::boost::mysql::detail::writable_field
  67. #else
  68. #define BOOST_MYSQL_WRITABLE_FIELD class
  69. #endif
  70. // field_view_forward_iterator
  71. template <typename T, typename = void>
  72. struct is_field_view_forward_iterator : std::false_type
  73. {
  74. };
  75. // clang-format off
  76. template <typename T>
  77. struct is_field_view_forward_iterator<
  78. T,
  79. typename std::enable_if<
  80. std::is_convertible<
  81. typename std::iterator_traits<T>::reference,
  82. field_view
  83. >::value
  84. &&
  85. std::is_base_of<
  86. std::forward_iterator_tag,
  87. typename std::iterator_traits<T>::iterator_category
  88. >::value
  89. >::type
  90. > : std::true_type { };
  91. // clang-format on
  92. #ifdef BOOST_MYSQL_HAS_CONCEPTS
  93. template <class T>
  94. concept field_view_forward_iterator = is_field_view_forward_iterator<T>::value;
  95. #define BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR ::boost::mysql::detail::field_view_forward_iterator
  96. #else // BOOST_MYSQL_HAS_CONCEPTS
  97. #define BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR class
  98. #endif // BOOST_MYSQL_HAS_CONCEPTS
  99. // writable_field_tuple
  100. template <class... T>
  101. struct is_writable_field_tuple_impl : std::false_type
  102. {
  103. };
  104. template <class... T>
  105. struct is_writable_field_tuple_impl<std::tuple<T...>>
  106. : mp11::mp_all_of<mp11::mp_list<typename std::remove_reference<T>::type...>, is_writable_field>
  107. {
  108. };
  109. template <class Tuple>
  110. struct is_writable_field_tuple : is_writable_field_tuple_impl<typename std::decay<Tuple>::type>
  111. {
  112. };
  113. #ifdef BOOST_MYSQL_HAS_CONCEPTS
  114. template <class T>
  115. concept writable_field_tuple = is_writable_field_tuple<T>::value;
  116. #define BOOST_MYSQL_WRITABLE_FIELD_TUPLE ::boost::mysql::detail::writable_field_tuple
  117. #else // BOOST_MYSQL_HAS_CONCEPTS
  118. #define BOOST_MYSQL_WRITABLE_FIELD_TUPLE class
  119. #endif // BOOST_MYSQL_HAS_CONCEPTS
  120. } // namespace detail
  121. } // namespace mysql
  122. } // namespace boost
  123. #endif