123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- //
- // Copyright (c) 2019-2024 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 BOOST_MYSQL_DETAIL_WRITABLE_FIELD_TRAITS_HPP
- #define BOOST_MYSQL_DETAIL_WRITABLE_FIELD_TRAITS_HPP
- #include <boost/mysql/field_view.hpp>
- #include <boost/mysql/detail/config.hpp>
- #include <type_traits>
- namespace boost {
- namespace mysql {
- namespace detail {
- template <class T, class En1 = void, class En2 = void>
- struct writable_field_traits
- {
- static constexpr bool is_supported = false;
- };
- template <>
- struct writable_field_traits<bool>
- {
- static constexpr bool is_supported = true;
- static field_view to_field(bool value) noexcept { return field_view(value ? 1 : 0); }
- };
- template <class T>
- struct writable_field_traits<
- T,
- typename std::enable_if<
- std::is_constructible<field_view, const T&>::value && std::is_object<T>::value>::type,
- void>
- {
- static constexpr bool is_supported = true;
- static field_view to_field(const T& value) noexcept { return field_view(value); }
- };
- // Optionals. To avoid dependencies, we use a "concept".
- // We consider a type an optional if has a `bool has_value() const` and
- // `const value_type& value() const`
- template <class T>
- struct writable_field_traits<
- T,
- void,
- typename std::enable_if<
- std::is_same<decltype(std::declval<const T&>().has_value()), bool>::value &&
- std::is_same<decltype(std::declval<const T&>().value()), const typename T::value_type&>::value>::type>
- {
- using value_traits = writable_field_traits<typename T::value_type>;
- static constexpr bool is_supported = value_traits::is_supported;
- static field_view to_field(const T& value) noexcept
- {
- return value.has_value() ? value_traits::to_field(value.value()) : field_view();
- }
- };
- template <class T>
- field_view to_field(const T& value) noexcept
- {
- return writable_field_traits<T>::to_field(value);
- }
- template <class T>
- struct is_writable_field : std::integral_constant<bool, writable_field_traits<T>::is_supported>
- {
- };
- #ifdef BOOST_MYSQL_HAS_CONCEPTS
- template <class T>
- concept writable_field = is_writable_field<T>::value;
- #define BOOST_MYSQL_WRITABLE_FIELD ::boost::mysql::detail::writable_field
- #else
- #define BOOST_MYSQL_WRITABLE_FIELD class
- #endif
- // field_view_forward_iterator
- template <typename T, typename = void>
- struct is_field_view_forward_iterator : std::false_type
- {
- };
- // clang-format off
- template <typename T>
- struct is_field_view_forward_iterator<
- T,
- typename std::enable_if<
- std::is_convertible<
- typename std::iterator_traits<T>::reference,
- field_view
- >::value
- &&
- std::is_base_of<
- std::forward_iterator_tag,
- typename std::iterator_traits<T>::iterator_category
- >::value
- >::type
- > : std::true_type { };
- // clang-format on
- #ifdef BOOST_MYSQL_HAS_CONCEPTS
- template <class T>
- concept field_view_forward_iterator = is_field_view_forward_iterator<T>::value;
- #define BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR ::boost::mysql::detail::field_view_forward_iterator
- #else // BOOST_MYSQL_HAS_CONCEPTS
- #define BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR class
- #endif // BOOST_MYSQL_HAS_CONCEPTS
- // writable_field_tuple
- template <class... T>
- struct is_writable_field_tuple_impl : std::false_type
- {
- };
- template <class... T>
- struct is_writable_field_tuple_impl<std::tuple<T...>>
- : mp11::mp_all_of<mp11::mp_list<typename std::remove_reference<T>::type...>, is_writable_field>
- {
- };
- template <class Tuple>
- struct is_writable_field_tuple : is_writable_field_tuple_impl<typename std::decay<Tuple>::type>
- {
- };
- #ifdef BOOST_MYSQL_HAS_CONCEPTS
- template <class T>
- concept writable_field_tuple = is_writable_field_tuple<T>::value;
- #define BOOST_MYSQL_WRITABLE_FIELD_TUPLE ::boost::mysql::detail::writable_field_tuple
- #else // BOOST_MYSQL_HAS_CONCEPTS
- #define BOOST_MYSQL_WRITABLE_FIELD_TUPLE class
- #endif // BOOST_MYSQL_HAS_CONCEPTS
- } // namespace detail
- } // namespace mysql
- } // namespace boost
- #endif
|