Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:42:54

0001 //
0002 // Copyright (c) 2019-2025 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_FORMAT_SQL_HPP
0009 #define BOOST_MYSQL_DETAIL_FORMAT_SQL_HPP
0010 
0011 #include <boost/mysql/constant_string_view.hpp>
0012 #include <boost/mysql/field_view.hpp>
0013 #include <boost/mysql/string_view.hpp>
0014 
0015 #include <boost/mysql/detail/writable_field_traits.hpp>
0016 
0017 #include <iterator>
0018 #include <type_traits>
0019 #include <utility>
0020 
0021 namespace boost {
0022 namespace mysql {
0023 
0024 // Forward decls
0025 template <class T>
0026 struct formatter;
0027 
0028 class format_context_base;
0029 class formattable_ref;
0030 class format_arg;
0031 
0032 namespace detail {
0033 
0034 class format_state;
0035 
0036 struct formatter_is_unspecialized
0037 {
0038 };
0039 
0040 template <class T>
0041 constexpr bool has_specialized_formatter()
0042 {
0043     return !std::is_base_of<formatter_is_unspecialized, formatter<typename std::decay<T>::type>>::value;
0044 }
0045 
0046 template <class T>
0047 struct is_writable_field_ref : is_writable_field<typename std::decay<T>::type>
0048 {
0049 };
0050 
0051 template <class T>
0052 struct is_formattable_ref : std::is_same<typename std::decay<T>::type, formattable_ref>
0053 {
0054 };
0055 
0056 // Is T suitable for being the element type of a formattable range?
0057 template <class T>
0058 constexpr bool is_formattable_range_elm_type()
0059 {
0060     return is_writable_field_ref<T>::value || has_specialized_formatter<T>() || is_formattable_ref<T>::value;
0061 }
0062 
0063 template <class T, class = void>
0064 struct is_formattable_range : std::false_type
0065 {
0066 };
0067 
0068 // Note: T might be a reference.
0069 // Using T& + reference collapsing gets the right semantics for non-const ranges
0070 template <class T>
0071 struct is_formattable_range<
0072     T,
0073     typename std::enable_if<
0074         // std::begin and std::end can be called on it, and we can compare values
0075         std::is_convertible<decltype(std::begin(std::declval<T&>()) != std::end(std::declval<T&>())), bool>::
0076             value &&
0077 
0078         // value_type is either a writable field or a type with a specialized formatter.
0079         // We don't support sequences of sequences out of the box (no known use case)
0080         is_formattable_range_elm_type<decltype(*std::begin(std::declval<T&>()))>()
0081 
0082         // end of conditions
0083         >::type> : std::true_type
0084 {
0085 };
0086 
0087 template <class T>
0088 constexpr bool is_formattable_type()
0089 {
0090     return is_formattable_range_elm_type<T>() || is_formattable_range<T>::value;
0091 }
0092 
0093 #ifdef BOOST_MYSQL_HAS_CONCEPTS
0094 
0095 // If you're getting an error referencing this concept,
0096 // it means that you are attempting to format a type that doesn't support it.
0097 template <class T>
0098 concept formattable =
0099     // This covers basic types and optionals
0100     is_writable_field_ref<T>::value ||
0101     // This covers custom types that specialized boost::mysql::formatter
0102     has_specialized_formatter<T>() ||
0103     // This covers ranges of formattable types
0104     is_formattable_range<T>::value ||
0105     // This covers passing formattable_ref as a format argument
0106     is_formattable_ref<T>::value;
0107 
0108 #define BOOST_MYSQL_FORMATTABLE ::boost::mysql::detail::formattable
0109 
0110 #else
0111 
0112 #define BOOST_MYSQL_FORMATTABLE class
0113 
0114 #endif
0115 
0116 // A type-erased argument passed to format. Built-in types are passed
0117 // directly in the struct (as a field_view), instead of by pointer,
0118 // to reduce the number of do_format instantiations
0119 struct formattable_ref_impl
0120 {
0121     enum class type_t
0122     {
0123         field,
0124         field_with_specs,
0125         fn_and_ptr
0126     };
0127 
0128     struct fn_and_ptr
0129     {
0130         const void* obj;
0131         bool (*format_fn)(const void*, const char*, const char*, format_context_base&);
0132     };
0133 
0134     union data_t
0135     {
0136         field_view fv;
0137         fn_and_ptr custom;
0138 
0139         data_t(field_view fv) noexcept : fv(fv) {}
0140         data_t(fn_and_ptr v) noexcept : custom(v) {}
0141     };
0142 
0143     type_t type;
0144     data_t data;
0145 };
0146 
0147 // Create a type-erased formattable_ref_impl from a formattable value
0148 template <class T>
0149 formattable_ref_impl make_formattable_ref(T&& v);
0150 
0151 BOOST_MYSQL_DECL
0152 void vformat_sql_to(format_context_base& ctx, constant_string_view format_str, span<const format_arg> args);
0153 
0154 }  // namespace detail
0155 }  // namespace mysql
0156 }  // namespace boost
0157 
0158 #endif