File indexing completed on 2025-04-09 08:28:04
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MYSQL_IMPL_FORMAT_SQL_HPP
0009 #define BOOST_MYSQL_IMPL_FORMAT_SQL_HPP
0010
0011 #pragma once
0012
0013 #include <boost/mysql/format_sql.hpp>
0014
0015 #include <boost/mysql/detail/format_sql.hpp>
0016
0017 #include <type_traits>
0018
0019 namespace boost {
0020 namespace mysql {
0021 namespace detail {
0022
0023 BOOST_MYSQL_DECL
0024 std::pair<bool, string_view> parse_range_specifiers(const char* spec_begin, const char* spec_end);
0025
0026
0027 template <class T>
0028 bool do_format_custom_formatter(
0029 const void* obj,
0030 const char* spec_begin,
0031 const char* spec_end,
0032 format_context_base& ctx
0033 )
0034 {
0035 formatter<T> fmt;
0036 const char* it = fmt.parse(spec_begin, spec_end);
0037 if (it != spec_end)
0038 {
0039 return false;
0040 }
0041 fmt.format(*static_cast<const T*>(obj), ctx);
0042 return true;
0043 }
0044
0045
0046 template <class T>
0047 bool do_format_range(const void* obj, const char* spec_begin, const char* spec_end, format_context_base& ctx)
0048 {
0049
0050 auto res = detail::parse_range_specifiers(spec_begin, spec_end);
0051 if (!res.first)
0052 return false;
0053 auto spec = runtime(res.second);
0054
0055
0056 auto& value = *const_cast<T*>(static_cast<const T*>(obj));
0057
0058
0059 bool is_first = true;
0060 for (auto it = std::begin(value); it != std::end(value); ++it)
0061 {
0062 if (!is_first)
0063 ctx.append_raw(", ");
0064 is_first = false;
0065 ctx.append_value(*it, spec);
0066 }
0067 return true;
0068 }
0069
0070
0071 inline formattable_ref_impl make_formattable_ref_custom(
0072 formattable_ref v,
0073 std::true_type
0074 )
0075 {
0076 return access::get_impl(v);
0077 }
0078
0079
0080 template <class T>
0081 formattable_ref_impl make_formattable_ref_custom(
0082 const T& v,
0083 std::false_type
0084 )
0085 {
0086
0087
0088 static_assert(
0089 has_specialized_formatter<T>(),
0090 "T is not formattable. Please use a formattable type or specialize formatter<T> to make it "
0091 "formattable"
0092 );
0093 return {
0094 formattable_ref_impl::type_t::fn_and_ptr,
0095 formattable_ref_impl::fn_and_ptr{&v, &do_format_custom_formatter<T>}
0096 };
0097 }
0098
0099
0100 template <class T>
0101 formattable_ref_impl make_formattable_ref_range(
0102 T&& v,
0103 std::true_type
0104 )
0105 {
0106
0107
0108 return {
0109 formattable_ref_impl::type_t::fn_and_ptr,
0110 formattable_ref_impl::fn_and_ptr{&v, &do_format_range<typename std::remove_reference<T>::type>}
0111 };
0112 }
0113
0114 template <class T>
0115 formattable_ref_impl make_formattable_ref_range(
0116 const T& v,
0117 std::false_type
0118 )
0119 {
0120 return make_formattable_ref_custom(v, is_formattable_ref<T>());
0121 }
0122
0123
0124 template <class T>
0125 formattable_ref_impl make_formattable_ref_writable(
0126 const T& v,
0127 std::true_type
0128 )
0129 {
0130
0131 return {
0132 std::is_convertible<T, string_view>::value ? formattable_ref_impl::type_t::field_with_specs
0133 : formattable_ref_impl::type_t::field,
0134 to_field(v)
0135 };
0136 }
0137
0138 template <class T>
0139 formattable_ref_impl make_formattable_ref_writable(
0140 T&& v,
0141 std::false_type
0142 )
0143 {
0144 return make_formattable_ref_range(std::forward<T>(v), is_formattable_range<T>());
0145 }
0146
0147 }
0148 }
0149 }
0150
0151 template <class T>
0152 boost::mysql::detail::formattable_ref_impl boost::mysql::detail::make_formattable_ref(T&& v)
0153 {
0154
0155
0156
0157
0158 return make_formattable_ref_writable(std::forward<T>(v), is_writable_field_ref<T>());
0159 }
0160
0161 template <BOOST_MYSQL_FORMATTABLE... Formattable>
0162 void boost::mysql::format_sql_to(
0163 format_context_base& ctx,
0164 constant_string_view format_str,
0165 Formattable&&... args
0166 )
0167 {
0168 std::initializer_list<format_arg> args_il{
0169 {string_view(), std::forward<Formattable>(args)}
0170 ...
0171 };
0172 format_sql_to(ctx, format_str, args_il);
0173 }
0174
0175 template <BOOST_MYSQL_FORMATTABLE... Formattable>
0176 std::string boost::mysql::format_sql(
0177 format_options opts,
0178 constant_string_view format_str,
0179 Formattable&&... args
0180 )
0181 {
0182 std::initializer_list<format_arg> args_il{
0183 {string_view(), std::forward<Formattable>(args)}
0184 ...
0185 };
0186 return format_sql(opts, format_str, args_il);
0187 }
0188
0189 #endif