File indexing completed on 2025-09-15 08:42:54
0001
0002
0003
0004
0005
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
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
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
0069
0070 template <class T>
0071 struct is_formattable_range<
0072 T,
0073 typename std::enable_if<
0074
0075 std::is_convertible<decltype(std::begin(std::declval<T&>()) != std::end(std::declval<T&>())), bool>::
0076 value &&
0077
0078
0079
0080 is_formattable_range_elm_type<decltype(*std::begin(std::declval<T&>()))>()
0081
0082
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
0096
0097 template <class T>
0098 concept formattable =
0099
0100 is_writable_field_ref<T>::value ||
0101
0102 has_specialized_formatter<T>() ||
0103
0104 is_formattable_range<T>::value ||
0105
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
0117
0118
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
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 }
0155 }
0156 }
0157
0158 #endif