1 #ifndef PQXX_INTERNAL_CONVERSIONS_HXX
2 #define PQXX_INTERNAL_CONVERSIONS_HXX
12 #include <type_traits>
30 return static_cast<char>(i +
'0');
53 template<
typename HAVE,
typename NEED>
58 static_cast<int>(have_bytes),
static_cast<int>(need_bytes));
82 template<pqxx::
internal::
char_type CHAR_TYPE>
85 static constexpr std::size_t
88 static constexpr std::string_view
89 to_buf(std::span<char>, CHAR_TYPE
const &,
ctx = {}) noexcept =
delete;
95 template<std::
floating_po
int T>
101 [[deprecated(
"into_buf() is no longer part of the string conversion API.")]]
106 auto const space{end - begin};
108 auto const len = std::size(text) + 1;
109 if (std::cmp_greater(len, space))
110 throw conversion_overrun{
111 std::format(
"Not enough buffer space to insert {}.", name_type<T>()) +
114 std::memmove(begin, std::data(text), len);
121 [[deprecated(
"into_buf() is no longer part of the string conversion API.")]]
125 auto const begin{std::data(buf)};
126 zview text{
to_buf(buf, value, c)};
127 auto const space{std::size(buf)};
129 auto const len = std::size(text) + 1;
130 if (std::cmp_greater(len, space))
131 throw conversion_overrun{
132 std::format(
"Not enough buffer space to insert {}. ", name_type<T>()) +
135 std::memmove(begin, std::data(text), len);
153 to_buf(std::span<char> buf, T
const &value,
ctx c = {});
156 static constexpr std::size_t
digits10(std::size_t value) noexcept
166 using lims = std::numeric_limits<T>;
190 auto const max_pos_exp{
digits10(lims::max_exponent10)};
193 auto const max_neg_exp{
194 digits10(lims::max_digits10 - lims::min_exponent10)};
197 std::numeric_limits<T>::max_digits10 +
202 (std::max)(max_pos_exp, max_neg_exp);
218 to_buf(std::span<char> buf, T
const &value,
ctx c = {});
226 return std::is_signed_v<T> + std::numeric_limits<T>::digits10 + 1;
243 template<pqxx::
internal::
integer T>
245 template<std::
floating_po
int T>
248 #define PQXX_SPECIALIZE_INT_TRAIT(typ) \
250 struct string_traits<typ> final \
251 : pqxx::internal::integer_string_traits<typ> \
263 #undef PQXX_SPECIALIZE_INT_TRAIT
282 static constexpr
zview
283 to_buf(std::span<char>,
bool const &value,
ctx = {}) noexcept
285 return value ?
"true"_zv :
"false"_zv;
288 static constexpr std::size_t
size_buffer(
bool const &) noexcept {
return 5; }
295 template<
typename T>
struct nullness<std::optional<T>> final
300 [[nodiscard]]
PQXX_PURE static constexpr
bool
305 [[nodiscard]]
PQXX_PURE static constexpr std::optional<T>
null() noexcept
321 static std::string_view
322 to_buf(std::span<char> buf, std::optional<T>
const &value,
ctx c = {})
334 return std::optional<T>{std::in_place, pqxx::from_string<T>(text, c)};
337 static std::size_t
size_buffer(std::optional<T>
const &value) noexcept
353 template<
typename... T>
struct nullness<std::variant<T...>> final
355 static constexpr
bool has_null = (pqxx::has_null<T>() or ...);
357 [[nodiscard]]
PQXX_PURE static constexpr
bool
358 is_null(std::variant<T...> const &value) noexcept
360 return value.valueless_by_exception() or
362 [](
auto const &i) noexcept {
372 static constexpr std::variant<T...>
null() =
delete;
378 static std::string_view
379 to_buf(std::span<char> buf, std::variant<T...>
const &value,
ctx c = {})
382 [buf, c](
auto const &i) {
383 using field_t = std::remove_cvref_t<decltype(i)>;
384 return pqxx::to_buf<field_t>(buf, i, c);
388 static std::size_t
size_buffer(std::variant<T...>
const &value) noexcept
405 template<
typename... Args>
408 return std::visit([](
auto &v) {
return param_format(v); }, value);
412 template<
typename... T>
420 return from_string<T>(text.str(), c);
426 [[deprecated(
"Do not convert nulls.")]]
static constexpr
zview
427 to_buf(std::span<char>, std::nullptr_t
const &,
ctx = {}) noexcept
432 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
443 [[deprecated(
"Do not convert nulls.")]]
static constexpr
zview
444 to_buf(
char *,
char *, std::nullopt_t
const &) noexcept
449 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
460 [[deprecated(
"Do not convert nulls.")]]
static constexpr
zview
461 to_buf(
char *,
char *, std::monostate
const &) noexcept
466 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
471 [[deprecated(
"Do not convert nulls.")]]
static std::monostate
476 template<>
inline constexpr
bool is_unquoted_safe<std::nullptr_t>{
true};
488 [[nodiscard]]
PQXX_PURE static constexpr
char const *
null() noexcept
510 to_buf(std::span<char>,
char const *
const &value,
ctx = {}) noexcept
522 return std::char_traits<char>::length(value);
535 [[nodiscard]]
PQXX_PURE static constexpr
char *
null() {
return nullptr; }
551 static std::string_view
552 to_buf(std::span<char> buf,
char *
const &value,
ctx c = {})
554 return pqxx::to_buf<char const *>(buf, value, c);
578 static constexpr
zview
579 to_buf(std::span<char>,
char const (&value)[N],
ctx = {}) noexcept
581 return zview{value, N - 1};
584 static constexpr std::size_t
size_buffer(
char const (&)[N]) noexcept
603 return std::string{
text};
607 to_buf(std::span<char>, std::string
const &value,
ctx = {})
609 return {std::data(value), std::size(value)};
615 return std::size(value);
640 return std::size(value);
644 to_buf(std::span<char>, std::string_view
const &value,
ctx = {})
667 return std::size(value);
691 static std::size_t
size_buffer(std::stringstream
const &) =
delete;
695 std::stringstream stream;
696 stream.write(
text.data(), std::streamsize(std::size(text)));
700 static std::string_view
701 to_buf(std::span<char>, std::stringstream
const &,
ctx = {}) =
delete;
715 :
all_null<std::monostate, std::monostate{}>
719 template<
typename T>
struct nullness<std::unique_ptr<T>> final
723 [[nodiscard]]
PQXX_PURE static constexpr
bool
728 [[nodiscard]]
PQXX_PURE static constexpr std::unique_ptr<T>
null() noexcept
735 template<
typename T,
typename... Args>
740 return std::make_unique<T>(pqxx::from_string<T>(text, c));
744 std::span<char> buf, std::unique_ptr<T, Args...>
const &value,
ctx c = {})
762 template<
typename T,
typename... Args>
769 template<
typename T,
typename... Args>
774 template<
typename T>
struct nullness<std::shared_ptr<T>> final
778 [[nodiscard]]
PQXX_PURE static constexpr
bool
783 [[nodiscard]]
PQXX_PURE static constexpr std::shared_ptr<T>
null() noexcept
794 return std::make_shared<T>(pqxx::from_string<T>(text, c));
797 static std::string_view
798 to_buf(std::span<char> buf, std::shared_ptr<T>
const &value,
ctx c = {})
804 static std::size_t
size_buffer(std::shared_ptr<T>
const &value) noexcept
821 inline constexpr
bool is_unquoted_safe<std::shared_ptr<T>>{
836 static std::string_view
837 to_buf(std::span<char> buf, DATA
const &value,
ctx c = {})
841 if (std::cmp_less(std::size(buf), budget))
842 throw conversion_overrun{
843 "Not enough buffer space to escape binary data.", c.loc};
847 return {std::data(buf), budget - 1};
855 if constexpr (
requires { buf.resize(std::size_t{}); })
865 if (std::size(buf) != size)
866 throw conversion_error{
868 "Can't convert binary data from SQL text to {}: I don't know how "
884 template<nonbinary_range TYPE>
886 std::span<char> buf, TYPE
const &value, std::size_t budget,
ctx c = {});
895 using elt_type = std::remove_cvref_t<value_type<T>>;
901 if constexpr (is_unquoted_safe<elt_type>)
902 return 3 + std::accumulate(
903 std::begin(value), std::end(value), std::size_t{},
904 [](std::size_t acc,
elt_type const &elt) {
916 return 3 + std::accumulate(
917 std::begin(value), std::end(value), std::size_t{},
918 [](std::size_t acc,
elt_type const &elt) {
921 std::size_t
const elt_size{
924 return acc + 2 * elt_size + 3;
928 static std::string_view
933 return {std::data(buf), sz};
941 template<nonbinary_range T>
struct nullness<T> final : no_null<T>
951 template<nonbinary_range T>
973 template<
typename TYPE>
978 std::format(
"Attempt to convert null to a string.", name_type<TYPE>()),
981 if constexpr (pqxx::always_null<TYPE>())
1017 template<>
inline std::string
to_string(std::stringstream
const &value,
ctx)
1023 template<
typename T>
1027 throw conversion_error{
1028 std::format(
"Attempt to convert null {} to a string.", name_type<T>()),
1034 auto const data{out.data()};
1035 auto const end{
into_buf({data, std::size(out)}, value, c)};
1036 out.resize(
static_cast<std::size_t
>(end - data));
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:55
#define PQXX_SPECIALIZE_INT_TRAIT(typ)
Definition: conversions.hxx:248
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:612
Private namespace for libpqxx's internal use; do not access.
Definition: connection.cxx:333
std::string to_string_float(T value, [[maybe_unused]] ctx c)
Floating-point implementations for pqxx::to_string().
Definition: strconv.cxx:327
char * generic_into_buf(char *begin, char *end, T const &value, ctx c={})
Generic implementation for into_buf(), on top of to_buf().
Definition: conversions.hxx:103
void unesc_bin(std::string_view escaped_data, std::span< std::byte > buffer, sl loc)
Reconstitute binary data from its escaped version.
Definition: util.cxx:194
constexpr PQXX_PURE std::size_t size_esc_bin(std::size_t binary_bytes) noexcept
Compute buffer size needed to escape binary data for use as a BYTEA.
Definition: util.hxx:493
void throw_null_conversion(std::string const &type, sl loc)
Throw exception for attempt to convert SQL NULL to given type.
Definition: strconv.cxx:142
constexpr PQXX_PURE int digit_to_number(char c) noexcept
Compute numeric value of given textual digit (assuming that it is a digit).
Definition: conversions.hxx:37
constexpr PQXX_PURE char number_to_digit(int i) noexcept
Convert a number in [0, 9] to its ASCII digit.
Definition: conversions.hxx:26
PQXX_INLINE_COV std::size_t array_into_buf(std::span< char > buf, TYPE const &value, std::size_t budget, ctx c)
Write an SQL array representation into buf.
Definition: array-composite.hxx:417
std::string state_buffer_overrun(int have_bytes, int need_bytes)
Summarize buffer overrun.
Definition: strconv.cxx:156
constexpr PQXX_PURE std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept
Compute binary size from the size of its escaped version.
Definition: util.hxx:505
void esc_bin(bytes_view binary_data, std::span< char > buffer) noexcept
Hex-escape binary data into a buffer.
Definition: util.cxx:159
The home of all libpqxx classes, functions, templates, etc.
Definition: array.cxx:26
std::string_view to_buf(std::span< char > buf, TYPE const &value, ctx c={})
Represent value as SQL text, optionally using buf as storage.
Definition: strconv.hxx:430
constexpr bool is_sql_array< T >
Definition: conversions.hxx:970
constexpr bool has_null() noexcept
Does TYPE have one or more inherent null values?
Definition: strconv.hxx:744
std::source_location sl
Convenience alias for std::source_location. It's just too long.
Definition: types.hxx:38
constexpr format param_format(std::optional< T > const &value)
Definition: conversions.hxx:313
constexpr std::string_view name_type() noexcept
Return human-readable name for TYPE.
Definition: types.hxx:277
T from_string(field const &value, ctx c={})
Convert a field's value to type T.
Definition: field.hxx:831
PQXX_LIBEXPORT std::string to_string(field_ref const &value, ctx)
Convert a field_ref to a string.
Definition: field.hxx:891
constexpr bool is_unquoted_safe< T >
Definition: conversions.hxx:244
constexpr std::size_t size_buffer(TYPE const &...value) noexcept
Estimate how much buffer space is needed to represent values as a string.
Definition: strconv.hxx:399
constexpr bool is_null(TYPE const &value) noexcept
Is value a null?
Definition: strconv.hxx:764
requires(pqxx::internal::to_buf_7< TYPE > or pqxx::internal::to_buf_8< TYPE >) const eval bool supports_to_buf_8()
Is the libpqxx 8 version of to_buf() supported for TYPE?
Definition: strconv.hxx:417
std::size_t into_buf(std::span< char > buf, TYPE const &value, ctx c={})
Write an SQL representation of value into buf.
Definition: strconv.hxx:454
constexpr bool is_unquoted_safe< bool >
Definition: conversions.hxx:292
conversion_context const & ctx
Convenience alias: const reference to a pqxx::conversion_context.
Definition: strconv.hxx:201
constexpr bool always_null() noexcept
Is a value of TYPE always null?
Definition: strconv.hxx:755
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition: strconv.hxx:812
format
Format code: is data text or binary?
Definition: types.hxx:121
void into_string(T const &value, std::string &out, ctx c={})
Definition: conversions.hxx:1024
Nullness traits describing a type whose values are always null.
Definition: strconv.hxx:133
Deliberately nonfunctional conversion traits for char types.
Definition: conversions.hxx:84
static constexpr std::size_t size_buffer(CHAR_TYPE const &) noexcept=delete
static constexpr std::string_view to_buf(std::span< char >, CHAR_TYPE const &, ctx={}) noexcept=delete
static CHAR_TYPE from_string(std::string_view, ctx={})=delete
String traits for builtin floating-point types.
Definition: conversions.hxx:149
static PQXX_LIBEXPORT T from_string(std::string_view text, ctx={})
Definition: strconv.cxx:345
static constexpr std::size_t digits10(std::size_t value) noexcept
Definition: conversions.hxx:156
static constexpr PQXX_INLINE_COV std::size_t size_buffer(T const &) noexcept
Definition: conversions.hxx:164
static PQXX_LIBEXPORT std::string_view to_buf(std::span< char > buf, T const &value, ctx c={})
Definition: strconv.cxx:357
String traits for builtin integer types.
Definition: conversions.hxx:215
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(T const &) noexcept
Definition: conversions.hxx:220
static PQXX_LIBEXPORT T from_string(std::string_view text, ctx={})
Definition: strconv.cxx:390
static PQXX_LIBEXPORT std::string_view to_buf(std::span< char > buf, T const &value, ctx c={})
Definition: strconv.cxx:398
Base class for string_traits specialisations for nonbinary ranges.
Definition: conversions.hxx:894
std::remove_cvref_t< value_type< T > > elt_type
Definition: conversions.hxx:895
static std::string_view to_buf(std::span< char > buf, T const &value, ctx c={})
Definition: conversions.hxx:929
static std::size_t size_buffer(T const &value) noexcept
Definition: conversions.hxx:899
static constexpr zview s_null
Definition: conversions.hxx:897
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:93
static constexpr PQXX_PURE bool is_null(char const *t) noexcept
Definition: conversions.hxx:531
PQXX_PURE static constexpr PQXX_ZARGS bool is_null(char const *t) noexcept
Definition: conversions.hxx:484
static constexpr PQXX_PURE bool is_null(std::optional< T > const &v) noexcept
Definition: conversions.hxx:301
static constexpr PQXX_PURE bool is_null(std::shared_ptr< T > const &t) noexcept
Definition: conversions.hxx:779
static constexpr PQXX_PURE bool is_null(std::unique_ptr< T > const &t) noexcept
Definition: conversions.hxx:724
Traits describing a type's "null value," if any.
Definition: strconv.hxx:70
static constexpr bool always_null
Is this type always null?
Definition: strconv.hxx:76
static PQXX_PURE bool is_null(TYPE const &value)
Is value a null?
static bool has_null
Does this type have a null value?
Definition: strconv.hxx:72
static std::string_view to_buf(std::span< char > buf, DATA const &value, ctx c={})
Definition: conversions.hxx:837
static DATA from_string(std::string_view text, ctx c={})
Convert a string to binary data.
Definition: conversions.hxx:851
static std::size_t size_buffer(DATA const &value) noexcept
Definition: conversions.hxx:831
static constexpr std::size_t size_buffer(bool const &) noexcept
Definition: conversions.hxx:288
static constexpr zview to_buf(std::span< char >, bool const &value, ctx={}) noexcept
Definition: conversions.hxx:283
static std::size_t size_buffer(char *const &value) noexcept
Definition: conversions.hxx:556
static std::string_view to_buf(std::span< char > buf, char *const &value, ctx c={})
Definition: conversions.hxx:552
static char * from_string(std::string_view, ctx={})=delete
constexpr static PQXX_ZARGS std::string_view to_buf(std::span< char >, char const *const &value, ctx={}) noexcept
Definition: conversions.hxx:510
static constexpr PQXX_ZARGS std::size_t size_buffer(char const *value) noexcept
Definition: conversions.hxx:516
static char const * from_string(std::string_view text, ctx={})=delete
static constexpr zview to_buf(std::span< char >, char const (&value)[N], ctx={}) noexcept
Definition: conversions.hxx:579
static void from_string(std::string_view, ctx={})=delete
Don't allow conversion to this type.
static constexpr std::size_t size_buffer(char const (&)[N]) noexcept
Definition: conversions.hxx:584
static constexpr zview to_buf(char *, char *, std::monostate const &) noexcept
Definition: conversions.hxx:461
static constexpr std::size_t size_buffer(std::monostate) noexcept
Definition: conversions.hxx:467
static std::monostate from_string(std::string_view, ctx={})=delete
static constexpr zview to_buf(char *, char *, std::nullopt_t const &) noexcept
Definition: conversions.hxx:444
static std::nullopt_t from_string(std::string_view, ctx={})=delete
static constexpr std::size_t size_buffer(std::nullopt_t) noexcept
Definition: conversions.hxx:450
static constexpr std::size_t size_buffer(std::nullptr_t=nullptr) noexcept
Definition: conversions.hxx:433
static constexpr zview to_buf(std::span< char >, std::nullptr_t const &, ctx={}) noexcept
Definition: conversions.hxx:427
static std::nullptr_t from_string(std::string_view, ctx={})=delete
static std::optional< T > from_string(std::string_view text, ctx c={})
Definition: conversions.hxx:332
static std::size_t size_buffer(std::optional< T > const &value) noexcept
Definition: conversions.hxx:337
static std::string_view to_buf(std::span< char > buf, std::optional< T > const &value, ctx c={})
Definition: conversions.hxx:322
static std::shared_ptr< T > from_string(std::string_view text, ctx c={})
Definition: conversions.hxx:792
static std::size_t size_buffer(std::shared_ptr< T > const &value) noexcept
Definition: conversions.hxx:804
static std::string_view to_buf(std::span< char > buf, std::shared_ptr< T > const &value, ctx c={})
Definition: conversions.hxx:798
static PQXX_INLINE_ONLY std::string from_string(std::string_view text, ctx={})
Definition: conversions.hxx:601
static PQXX_INLINE_ONLY std::string_view to_buf(std::span< char >, std::string const &value, ctx={})
Definition: conversions.hxx:607
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(std::string const &value) noexcept
Definition: conversions.hxx:613
static PQXX_INLINE_ONLY std::string_view from_string(std::string_view value, ctx={})
Definition: conversions.hxx:650
static PQXX_INLINE_ONLY std::string_view to_buf(std::span< char >, std::string_view const &value, ctx={})
Definition: conversions.hxx:644
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(std::string_view const &value) noexcept
Definition: conversions.hxx:638
static std::stringstream from_string(std::string_view text, ctx={})
Definition: conversions.hxx:693
static std::size_t size_buffer(std::stringstream const &)=delete
static std::string_view to_buf(std::span< char >, std::stringstream const &, ctx={})=delete
static std::string_view to_buf(std::span< char > buf, std::unique_ptr< T, Args... > const &value, ctx c={})
Definition: conversions.hxx:743
static std::size_t size_buffer(std::unique_ptr< T, Args... > const &value) noexcept
Definition: conversions.hxx:752
static std::unique_ptr< T > from_string(std::string_view text, ctx c={})
Definition: conversions.hxx:738
static std::variant< T... > from_string(std::string_view, ctx={})=delete
static std::string_view to_buf(std::span< char > buf, std::variant< T... > const &value, ctx c={})
Definition: conversions.hxx:379
static std::size_t size_buffer(std::variant< T... > const &value) noexcept
Definition: conversions.hxx:388
static zview from_string(std::string_view, ctx={})=delete
Don't convert to this type. There may not be a terminating zero.
static constexpr zview to_buf(std::span< char >, zview const &value, ctx={})
Definition: conversions.hxx:670
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(std::string_view const &value) noexcept
Definition: conversions.hxx:665
Traits class for use in string conversions.
Definition: strconv.hxx:213
static std::size_t size_buffer(TYPE const &value) noexcept
Estimate how much buffer space is needed to represent value as SQL text.
static TYPE from_string(std::string_view text, ctx={})
Parse a string representation of a TYPE value.
Definition: time.cxx:198
#define PQXX_UNREACHABLE
Definition: util.hxx:51