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);
154 to_buf(std::span<char> buf, T
const &value,
ctx c = {});
168 using lims = std::numeric_limits<T>;
192 auto const max_pos_exp{
digits10(lims::max_exponent10)};
195 auto const max_neg_exp{
196 digits10(lims::max_digits10 - lims::min_exponent10)};
199 std::numeric_limits<T>::max_digits10 +
204 (std::max)(max_pos_exp, max_neg_exp);
221 to_buf(std::span<char> buf, T
const &value,
ctx c = {});
230 return std::is_signed_v<T> + std::numeric_limits<T>::digits10 + 1;
247 template<pqxx::
internal::
integer T>
249 template<std::
floating_po
int T>
252 #define PQXX_SPECIALIZE_INT_TRAIT(typ) \
254 struct string_traits<typ> final \
255 : pqxx::internal::integer_string_traits<typ> \
267 #undef PQXX_SPECIALIZE_INT_TRAIT
288 to_buf(std::span<char>,
bool const &value,
ctx = {}) noexcept
290 return value ?
"true" :
"false";
304 template<
typename T>
struct nullness<std::optional<T>> final
331 static std::string_view
332 to_buf(std::span<char> buf, std::optional<T>
const &value,
ctx c = {})
344 return std::optional<T>{std::in_place, pqxx::from_string<T>(text, c)};
347 static std::size_t
size_buffer(std::optional<T>
const &value) noexcept
363 template<
typename... T>
struct nullness<std::variant<T...>> final
365 static constexpr
bool has_null = (pqxx::has_null<T>() or ...);
367 [[nodiscard]]
PQXX_PURE static constexpr
bool
368 is_null(std::variant<T...> const &value) noexcept
370 return value.valueless_by_exception() or
372 [](
auto const &i) noexcept {
382 static constexpr std::variant<T...>
null() =
delete;
388 static std::string_view
389 to_buf(std::span<char> buf, std::variant<T...>
const &value,
ctx c = {})
392 [buf, c](
auto const &i) {
393 using field_t = std::remove_cvref_t<decltype(i)>;
394 return pqxx::to_buf<field_t>(buf, i, c);
398 static std::size_t
size_buffer(std::variant<T...>
const &value) noexcept
415 template<
typename... Args>
418 return std::visit([](
auto &v) {
return param_format(v); }, value);
422 template<
typename... T>
430 return from_string<T>(text.str(), c);
436 [[deprecated(
"Do not convert nulls.")]]
static constexpr
zview
437 to_buf(std::span<char>, std::nullptr_t
const &,
ctx = {}) noexcept
442 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
453 [[deprecated(
"Do not convert nulls.")]]
static constexpr
zview
454 to_buf(
char *,
char *, std::nullopt_t
const &) noexcept
459 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
470 [[deprecated(
"Do not convert nulls.")]]
static constexpr
zview
471 to_buf(
char *,
char *, std::monostate
const &) noexcept
476 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
481 [[deprecated(
"Do not convert nulls.")]]
static std::monostate
486 template<>
inline constexpr
bool is_unquoted_safe<std::nullptr_t>{
true};
498 [[nodiscard]]
PQXX_PURE static constexpr
char const *
null() noexcept
520 to_buf(std::span<char>,
char const *
const &value,
ctx = {}) noexcept
532 return std::char_traits<char>::length(value);
545 [[nodiscard]]
PQXX_PURE static constexpr
char *
null() {
return nullptr; }
561 static std::string_view
562 to_buf(std::span<char> buf,
char *
const &value,
ctx c = {})
564 return pqxx::to_buf<char const *>(buf, value, c);
588 static constexpr
zview
589 to_buf(std::span<char>,
char const (&value)[N],
ctx = {}) noexcept
591 return zview{value, N - 1};
594 static constexpr std::size_t
size_buffer(
char const (&)[N]) noexcept
613 return std::string{
text};
617 to_buf(std::span<char>, std::string
const &value,
ctx = {})
619 return {std::data(value), std::size(value)};
625 return std::size(value);
650 return std::size(value);
654 to_buf(std::span<char>, std::string_view
const &value,
ctx = {})
677 return std::size(value);
701 static std::size_t
size_buffer(std::stringstream
const &) =
delete;
705 std::stringstream stream;
706 stream.write(
text.data(), std::streamsize(std::size(text)));
710 static std::string_view
711 to_buf(std::span<char>, std::stringstream
const &,
ctx = {}) =
delete;
725 :
all_null<std::monostate, std::monostate{}>
729 template<
typename T>
struct nullness<std::unique_ptr<T>> final
733 [[nodiscard]]
PQXX_PURE static constexpr
bool
738 [[nodiscard]]
PQXX_PURE static constexpr std::unique_ptr<T>
null() noexcept
745 template<
typename T,
typename... Args>
750 return std::make_unique<T>(pqxx::from_string<T>(text, c));
754 std::span<char> buf, std::unique_ptr<T, Args...>
const &value,
ctx c = {})
772 template<
typename T,
typename... Args>
779 template<
typename T,
typename... Args>
784 template<
typename T>
struct nullness<std::shared_ptr<T>> final
788 [[nodiscard]]
PQXX_PURE static constexpr
bool
793 [[nodiscard]]
PQXX_PURE static constexpr std::shared_ptr<T>
null() noexcept
804 return std::make_shared<T>(pqxx::from_string<T>(text, c));
807 static std::string_view
808 to_buf(std::span<char> buf, std::shared_ptr<T>
const &value,
ctx c = {})
814 static std::size_t
size_buffer(std::shared_ptr<T>
const &value) noexcept
831 inline constexpr
bool is_unquoted_safe<std::shared_ptr<T>>{
846 static std::string_view
847 to_buf(std::span<char> buf, DATA
const &value,
ctx c = {})
851 if (std::cmp_less(std::size(buf), budget))
852 throw conversion_overrun{
853 "Not enough buffer space to escape binary data.", c.loc};
857 return {std::data(buf), budget - 1};
865 if constexpr (
requires { buf.resize(std::size_t{}); })
875 if (std::size(buf) != size)
876 throw conversion_error{
878 "Can't convert binary data from SQL text to {}: I don't know how "
894 template<nonbinary_range TYPE>
896 std::span<char> buf, TYPE
const &value, std::size_t budget,
ctx c = {});
905 using elt_type = std::remove_cvref_t<value_type<T>>;
911 if constexpr (is_unquoted_safe<elt_type>)
912 return 3 + std::accumulate(
913 std::begin(value), std::end(value), std::size_t{},
914 [](std::size_t acc,
elt_type const &elt) {
921 return 3 + std::accumulate(
922 std::begin(value), std::end(value), std::size_t{},
923 [](std::size_t acc,
elt_type const &elt) {
926 std::size_t
const elt_size{
929 return acc + 2 * elt_size + 3;
933 static std::string_view
938 return {std::data(buf), sz};
946 template<nonbinary_range T>
struct nullness<T> final : no_null<T>
956 template<nonbinary_range T>
978 template<
typename TYPE>
983 std::format(
"Attempt to convert null to a string.", name_type<TYPE>()),
986 if constexpr (pqxx::always_null<TYPE>())
1022 template<>
inline std::string
to_string(std::stringstream
const &value,
ctx)
1028 template<
typename T>
1032 throw conversion_error{
1033 std::format(
"Attempt to convert null {} to a string.", name_type<T>()),
1039 auto const data{out.data()};
1040 auto const end{
into_buf({data, std::size(out)}, value, c)};
1041 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:252
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
PQXX_PURE constexpr PQXX_HOT int digit_to_number(char c) noexcept
Compute numeric value of given textual digit (assuming that it is a digit).
Definition: conversions.hxx:37
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
std::string state_buffer_overrun(int have_bytes, int need_bytes)
Summarize buffer overrun.
Definition: strconv.cxx:156
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
PQXX_PURE constexpr PQXX_HOT 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:419
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:975
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:323
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:248
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:301
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:1029
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 constexpr PQXX_HOT std::size_t digits10(std::size_t value) noexcept
Definition: conversions.hxx:157
PQXX_LIBEXPORT static PQXX_HOT T from_string(std::string_view text, ctx={})
Definition: strconv.cxx:345
PQXX_HOT static constexpr PQXX_INLINE_COV std::size_t size_buffer(T const &) noexcept
Definition: conversions.hxx:166
PQXX_LIBEXPORT static PQXX_HOT 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:217
PQXX_INLINE_ONLY static constexpr PQXX_HOT std::size_t size_buffer(T const &) noexcept
Definition: conversions.hxx:224
PQXX_LIBEXPORT static PQXX_HOT T from_string(std::string_view text, ctx={})
Definition: strconv.cxx:390
PQXX_LIBEXPORT static PQXX_HOT 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:904
std::remove_cvref_t< value_type< T > > elt_type
Definition: conversions.hxx:905
static std::string_view to_buf(std::span< char > buf, T const &value, ctx c={})
Definition: conversions.hxx:934
static std::size_t size_buffer(T const &value) noexcept
Definition: conversions.hxx:909
static constexpr zview s_null
Definition: conversions.hxx:907
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:541
PQXX_PURE static constexpr PQXX_ZARGS bool is_null(char const *t) noexcept
Definition: conversions.hxx:494
PQXX_PURE static constexpr PQXX_HOT bool is_null(std::optional< T > const &v) noexcept
Definition: conversions.hxx:310
static constexpr PQXX_PURE bool is_null(std::shared_ptr< T > const &t) noexcept
Definition: conversions.hxx:789
static constexpr PQXX_PURE bool is_null(std::unique_ptr< T > const &t) noexcept
Definition: conversions.hxx:734
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:847
static DATA from_string(std::string_view text, ctx c={})
Convert a string to binary data.
Definition: conversions.hxx:861
static std::size_t size_buffer(DATA const &value) noexcept
Definition: conversions.hxx:841
PQXX_PURE static constexpr PQXX_HOT std::string_view to_buf(std::span< char >, bool const &value, ctx={}) noexcept
Definition: conversions.hxx:288
PQXX_PURE static constexpr PQXX_HOT std::size_t size_buffer(bool const &) noexcept
Definition: conversions.hxx:294
static std::size_t size_buffer(char *const &value) noexcept
Definition: conversions.hxx:566
static std::string_view to_buf(std::span< char > buf, char *const &value, ctx c={})
Definition: conversions.hxx:562
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:520
static constexpr PQXX_ZARGS std::size_t size_buffer(char const *value) noexcept
Definition: conversions.hxx:526
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:589
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:594
static constexpr zview to_buf(char *, char *, std::monostate const &) noexcept
Definition: conversions.hxx:471
static constexpr std::size_t size_buffer(std::monostate) noexcept
Definition: conversions.hxx:477
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:454
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:460
static constexpr std::size_t size_buffer(std::nullptr_t=nullptr) noexcept
Definition: conversions.hxx:443
static constexpr zview to_buf(std::span< char >, std::nullptr_t const &, ctx={}) noexcept
Definition: conversions.hxx:437
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:342
static std::size_t size_buffer(std::optional< T > const &value) noexcept
Definition: conversions.hxx:347
static std::string_view to_buf(std::span< char > buf, std::optional< T > const &value, ctx c={})
Definition: conversions.hxx:332
static std::shared_ptr< T > from_string(std::string_view text, ctx c={})
Definition: conversions.hxx:802
static std::size_t size_buffer(std::shared_ptr< T > const &value) noexcept
Definition: conversions.hxx:814
static std::string_view to_buf(std::span< char > buf, std::shared_ptr< T > const &value, ctx c={})
Definition: conversions.hxx:808
static PQXX_INLINE_ONLY std::string from_string(std::string_view text, ctx={})
Definition: conversions.hxx:611
static PQXX_INLINE_ONLY std::string_view to_buf(std::span< char >, std::string const &value, ctx={})
Definition: conversions.hxx:617
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(std::string const &value) noexcept
Definition: conversions.hxx:623
static PQXX_INLINE_ONLY std::string_view from_string(std::string_view value, ctx={})
Definition: conversions.hxx:660
static PQXX_INLINE_ONLY std::string_view to_buf(std::span< char >, std::string_view const &value, ctx={})
Definition: conversions.hxx:654
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(std::string_view const &value) noexcept
Definition: conversions.hxx:648
static std::stringstream from_string(std::string_view text, ctx={})
Definition: conversions.hxx:703
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:753
static std::size_t size_buffer(std::unique_ptr< T, Args... > const &value) noexcept
Definition: conversions.hxx:762
static std::unique_ptr< T > from_string(std::string_view text, ctx c={})
Definition: conversions.hxx:748
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:389
static std::size_t size_buffer(std::variant< T... > const &value) noexcept
Definition: conversions.hxx:398
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:680
static constexpr PQXX_INLINE_ONLY std::size_t size_buffer(std::string_view const &value) noexcept
Definition: conversions.hxx:675
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