8#if defined(PQXX_HAVE_SPAN) && __has_include(<span>)
16#include "pqxx/types.hxx"
17#include "pqxx/util.hxx"
29 return static_cast<char>(i +
'0');
44std::string PQXX_LIBEXPORT
48template<
typename HAVE,
typename NEED>
52 static_cast<int>(have_bytes),
static_cast<int>(need_bytes));
57[[noreturn]] PQXX_LIBEXPORT PQXX_COLD
void
62[[noreturn]] PQXX_LIBEXPORT PQXX_COLD
void
78 static constexpr bool converts_to_string{
false};
79 static constexpr bool converts_from_string{
false};
80 static char *into_buf(
char *,
char *, CHAR_TYPE) =
delete;
81 static constexpr zview
82 to_buf(
char *,
char *, CHAR_TYPE
const &)
noexcept =
delete;
84 static constexpr std::size_t
85 size_buffer(CHAR_TYPE
const &)
noexcept =
delete;
86 static CHAR_TYPE from_string(std::string_view) =
delete;
90template<
typename T> PQXX_LIBEXPORT
extern std::string
to_string_float(T);
98 auto const space{end - begin};
100 auto const len = std::size(text) + 1;
103 "Not enough buffer space to insert " +
type_name<T> +
". " +
105 std::memmove(begin, text.data(), len);
114 static constexpr bool converts_to_string{
true};
115 static constexpr bool converts_from_string{
true};
116 static PQXX_LIBEXPORT T from_string(std::string_view text);
117 static PQXX_LIBEXPORT
zview to_buf(
char *begin,
char *end, T
const &value);
118 static PQXX_LIBEXPORT
char *into_buf(
char *begin,
char *end, T
const &value);
120 static constexpr std::size_t size_buffer(T
const &)
noexcept
126 return std::is_signed_v<T> + std::numeric_limits<T>::digits10 + 1 + 1;
135 static constexpr bool converts_to_string{
true};
136 static constexpr bool converts_from_string{
true};
137 static PQXX_LIBEXPORT T from_string(std::string_view text);
138 static PQXX_LIBEXPORT
zview to_buf(
char *begin,
char *end, T
const &value);
139 static PQXX_LIBEXPORT
char *into_buf(
char *begin,
char *end, T
const &value);
142 static constexpr std::size_t digits10(std::size_t value)
noexcept
147 return 1 + digits10(value / 10);
150 static constexpr std::size_t size_buffer(T
const &)
noexcept
152 using lims = std::numeric_limits<T>;
176 auto const max_pos_exp{digits10(lims::max_exponent10)};
179 auto const max_neg_exp{
180 digits10(lims::max_digits10 - lims::min_exponent10)};
183 std::numeric_limits<T>::max_digits10 +
188 (std::max)(max_pos_exp, max_neg_exp) +
250 static constexpr bool converts_to_string{
true};
251 static constexpr bool converts_from_string{
true};
253 static PQXX_LIBEXPORT
bool from_string(std::string_view text);
255 static constexpr zview to_buf(
char *,
char *,
bool const &value)
noexcept
257 return value ?
"true"_zv :
"false"_zv;
260 static char *
into_buf(
char *begin,
char *end,
bool const &value)
265 static constexpr std::size_t
size_buffer(
bool const &)
noexcept {
return 6; }
272template<
typename T>
struct nullness<std::optional<T>>
274 static constexpr bool has_null =
true;
277 static constexpr bool is_null(std::optional<T>
const &v)
noexcept
281 static constexpr std::optional<T>
null() {
return {}; }
286inline constexpr format param_format(std::optional<T>
const &value)
288 return param_format(*value);
294 static constexpr bool converts_to_string{
296 static constexpr bool converts_from_string{
299 static char *
into_buf(
char *begin,
char *end, std::optional<T>
const &value)
304 static zview to_buf(
char *begin,
char *end, std::optional<T>
const &value)
312 static std::optional<T>
from_string(std::string_view text)
314 return std::optional<T>{
318 static std::size_t
size_buffer(std::optional<T>
const &value)
noexcept
332template<
typename... T>
struct nullness<std::variant<T...>>
336 static constexpr bool is_null(std::variant<T...>
const &value)
noexcept
338 return value.valueless_by_exception() or
340 [](
auto const &i)
noexcept {
350 static constexpr std::variant<T...>
null() =
delete;
356 static constexpr bool converts_to_string{
360 into_buf(
char *begin,
char *end, std::variant<T...>
const &value)
363 [begin, end](
auto const &i) {
368 static zview to_buf(
char *begin,
char *end, std::variant<T...>
const &value)
371 [begin, end](
auto const &i) {
376 static std::size_t
size_buffer(std::variant<T...>
const &value)
noexcept
393template<
typename... Args>
394inline constexpr format param_format(std::variant<Args...>
const &value)
396 return std::visit([](
auto &v) {
return param_format(v); }, value);
400template<
typename... T>
405template<
typename T>
inline T
from_string(std::stringstream
const &text)
413 static constexpr bool converts_to_string{
false};
414 static constexpr bool converts_from_string{
false};
416 static char *
into_buf(
char *,
char *, std::nullptr_t) =
delete;
418 [[deprecated(
"Do not convert nulls.")]]
static constexpr zview
419 to_buf(
char *,
char *, std::nullptr_t
const &)
noexcept
424 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
429 static std::nullptr_t
from_string(std::string_view) =
delete;
435 static constexpr bool converts_to_string{
false};
436 static constexpr bool converts_from_string{
false};
438 static char *
into_buf(
char *,
char *, std::nullopt_t) =
delete;
440 [[deprecated(
"Do not convert nulls.")]]
static constexpr zview
441 to_buf(
char *,
char *, std::nullopt_t
const &)
noexcept
446 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
451 static std::nullopt_t
from_string(std::string_view) =
delete;
457 static constexpr bool converts_to_string{
false};
458 static constexpr bool converts_from_string{
false};
460 static char *
into_buf(
char *,
char *, std::monostate) =
delete;
462 [[deprecated(
"Do not convert nulls.")]]
static constexpr zview
463 to_buf(
char *,
char *, std::monostate
const &)
noexcept
468 [[deprecated(
"Do not convert nulls.")]]
static constexpr std::size_t
473 [[deprecated(
"Do not convert nulls.")]]
static std::monostate
483 static constexpr bool has_null =
true;
484 static constexpr bool always_null =
false;
485 static constexpr bool is_null(
char const *t)
noexcept
489 static constexpr char const *null()
noexcept {
return nullptr; }
496 static constexpr bool converts_to_string{
true};
497 static constexpr bool converts_from_string{
true};
499 static char const *
from_string(std::string_view text) {
return text.data(); }
501 static zview to_buf(
char *begin,
char *end,
char const *
const &value)
506 static char *into_buf(
char *begin,
char *end,
char const *
const &value)
508 auto const space{end - begin};
510 auto const len{std::strlen(value) + 1};
511 if (space < ptrdiff_t(len))
513 "Could not copy string: buffer too small. " +
515 std::memmove(begin, value, len);
519 static std::size_t
size_buffer(
char const *
const &value)
noexcept
524 return std::strlen(value) + 1;
531 static constexpr bool has_null =
true;
532 static constexpr bool always_null =
false;
533 static constexpr bool is_null(
char const *t)
noexcept
537 static constexpr char const *null() {
return nullptr; }
544 static constexpr bool converts_to_string{
true};
545 static constexpr bool converts_from_string{
false};
547 static char *into_buf(
char *begin,
char *end,
char *
const &value)
551 static zview to_buf(
char *begin,
char *end,
char *
const &value)
555 static std::size_t
size_buffer(
char *
const &value)
noexcept
578 static constexpr bool converts_to_string{
true};
579 static constexpr bool converts_from_string{
false};
581 static constexpr zview
582 to_buf(
char *,
char *,
char const (&value)[N])
noexcept
584 return zview{value, N - 1};
587 static char *
into_buf(
char *begin,
char *end,
char const (&value)[N])
591 "Could not convert char[] to string: too long for buffer."};
592 std::memcpy(begin, value, N);
595 static constexpr std::size_t
size_buffer(
char const (&)[N])
noexcept
611 static constexpr bool converts_to_string{
true};
612 static constexpr bool converts_from_string{
true};
614 static std::string
from_string(std::string_view text)
616 return std::string{text};
619 static char *
into_buf(
char *begin,
char *end, std::string
const &value)
623 "Could not convert string to string: too long for buffer."};
625 value.copy(begin, std::size(value));
626 begin[std::size(value)] =
'\0';
627 return begin + std::size(value) + 1;
630 static zview to_buf(
char *begin,
char *end, std::string
const &value)
635 static std::size_t
size_buffer(std::string
const &value)
noexcept
637 return std::size(value) + 1;
653 static constexpr bool converts_to_string{
true};
654 static constexpr bool converts_from_string{
false};
656 static constexpr std::size_t
657 size_buffer(std::string_view
const &value)
noexcept
659 return std::size(value) + 1;
662 static char *
into_buf(
char *begin,
char *end, std::string_view
const &value)
666 "Could not store string_view: too long for buffer."};
667 value.copy(begin, std::size(value));
668 begin[std::size(value)] =
'\0';
669 return begin + std::size(value) + 1;
672 static zview to_buf(
char *begin,
char *end, std::string_view
const &value)
691 static constexpr bool converts_to_string{
true};
692 static constexpr bool converts_from_string{
false};
694 static constexpr std::size_t
695 size_buffer(std::string_view
const &value)
noexcept
697 return std::size(value) + 1;
700 static char *
into_buf(
char *begin,
char *end,
zview const &value)
702 auto const size{std::size(value)};
705 value.copy(begin, size);
707 return begin + size + 1;
710 static std::string_view
to_buf(
char *begin,
char *end,
zview const &value)
712 char *
const stop{
into_buf(begin, end, value)};
713 return {begin,
static_cast<std::size_t
>(stop - begin - 1)};
727 static constexpr bool converts_to_string{
false};
728 static constexpr bool converts_from_string{
true};
730 static std::size_t
size_buffer(std::stringstream
const &) =
delete;
732 static std::stringstream
from_string(std::string_view text)
734 std::stringstream stream;
735 stream.write(text.data(), std::streamsize(std::size(text)));
739 static char *
into_buf(
char *,
char *, std::stringstream
const &) =
delete;
740 static std::string_view
741 to_buf(
char *,
char *, std::stringstream
const &) =
delete;
747 static constexpr bool has_null =
true;
748 static constexpr bool always_null =
true;
749 static constexpr bool is_null(std::nullptr_t
const &)
noexcept
753 static constexpr std::nullptr_t
null()
noexcept {
return nullptr; }
759 static constexpr bool has_null =
true;
760 static constexpr bool always_null =
true;
761 static constexpr bool is_null(std::nullopt_t
const &)
noexcept
765 static constexpr std::nullopt_t
null()
noexcept {
return std::nullopt; }
771 static constexpr bool has_null =
true;
772 static constexpr bool always_null =
true;
773 static constexpr bool is_null(std::monostate
const &)
noexcept
777 static constexpr std::monostate
null()
noexcept {
return {}; }
781template<
typename T>
struct nullness<std::unique_ptr<T>>
783 static constexpr bool has_null =
true;
784 static constexpr bool always_null =
false;
785 static constexpr bool is_null(std::unique_ptr<T>
const &t)
noexcept
789 static constexpr std::unique_ptr<T>
null() {
return {}; }
793template<
typename T,
typename... Args>
796 static constexpr bool converts_to_string{
798 static constexpr bool converts_from_string{
801 static std::unique_ptr<T>
from_string(std::string_view text)
807 into_buf(
char *begin,
char *end, std::unique_ptr<T, Args...>
const &value)
813 to_buf(
char *begin,
char *end, std::unique_ptr<T, Args...>
const &value)
822 size_buffer(std::unique_ptr<T, Args...>
const &value)
noexcept
832template<
typename T,
typename... Args>
833inline format param_format(std::unique_ptr<T, Args...>
const &value)
835 return param_format(*value);
839template<
typename T,
typename... Args>
844template<
typename T>
struct nullness<std::shared_ptr<T>>
846 static constexpr bool has_null =
true;
847 static constexpr bool always_null =
false;
848 static constexpr bool is_null(std::shared_ptr<T>
const &t)
noexcept
852 static constexpr std::shared_ptr<T>
null() {
return {}; }
858 static constexpr bool converts_to_string{
860 static constexpr bool converts_from_string{
863 static std::shared_ptr<T>
from_string(std::string_view text)
868 static zview to_buf(
char *begin,
char *end, std::shared_ptr<T>
const &value)
873 into_buf(
char *begin,
char *end, std::shared_ptr<T>
const &value)
877 static std::size_t
size_buffer(std::shared_ptr<T>
const &value)
noexcept
887template<
typename T>
format param_format(std::shared_ptr<T>
const &value)
889 return param_format(*value);
902#if defined(PQXX_HAVE_CONCEPTS)
907template<binary DATA>
inline constexpr format param_format(DATA
const &)
909 return format::binary;
918 static std::size_t
size_buffer(DATA
const &value)
noexcept
923 static zview
to_buf(
char *begin,
char *end, DATA
const &value)
928 static char *
into_buf(
char *begin,
char *end, DATA
const &value)
932 throw conversion_overrun{
933 "Not enough buffer space to escape binary data."};
935 return begin + budget;
952 static constexpr bool converts_to_string{
true};
953 static constexpr bool converts_from_string{
true};
965 static char *
into_buf(
char *begin,
char *end,
bytes const &value)
970 "Not enough buffer space to escape binary data."};
972 return begin + budget;
986template<>
inline constexpr format param_format(
bytes const &)
988 return format::binary;
998 static constexpr bool converts_to_string{
true};
999 static constexpr bool converts_from_string{
false};
1016 "Not enough buffer space to escape binary data."};
1018 return begin + budget;
1026 return format::binary;
1040 static constexpr zview s_null{
"NULL"};
1043 static constexpr bool converts_to_string{
true};
1044 static constexpr bool converts_from_string{
false};
1046 static zview to_buf(
char *begin,
char *end, Container
const &value)
1051 static char *into_buf(
char *begin,
char *end, Container
const &value)
1053 assert(begin <= end);
1054 std::size_t
const budget{size_buffer(value)};
1057 "Not enough buffer space to convert array to string."};
1062 bool nonempty{
false};
1063 for (
auto const &elt : value)
1067 s_null.copy(here, std::size(s_null));
1068 here += std::size(s_null);
1088 assert(elt_budget <
static_cast<std::size_t
>(end - here));
1094 if (c ==
'\\' or c ==
'"')
1114 static std::size_t size_buffer(Container
const &value)
noexcept
1117 return 3 + std::accumulate(
1118 std::begin(value), std::end(value), std::size_t{},
1119 [](std::size_t acc, elt_type
const &elt) {
1127 (std::size(s_null) + 1) :
1131 return 3 + std::accumulate(
1132 std::begin(value), std::end(value), std::size_t{},
1133 [](std::size_t acc, elt_type
const &elt) {
1139 std::size_t
const elt_size{
1142 return acc + 2 * elt_size + 2;
1154template<
typename T,
typename... Args>
1159template<
typename T,
typename... Args>
1166template<
typename T,
typename... Args>
1167inline constexpr format param_format(std::vector<T, Args...>
const &)
1169 return format::text;
1174template<
typename... Args>
1175inline constexpr format param_format(std::vector<std::byte, Args...>
const &)
1177 return format::binary;
1184#if defined(PQXX_HAVE_SPAN) && __has_include(<span>)
1185template<
typename T,
size_t Extent>
1190template<
typename T,
size_t Extent>
1196template<
typename T,
size_t Extent>
1197inline constexpr format param_format(std::span<T, Extent>
const &)
1199 return format::text;
1203template<
size_t Extent>
1204inline constexpr format param_format(std::span<std::byte, Extent>
const &)
1206 return format::binary;
1210template<
typename T,
size_t Extent>
1215template<
typename T, std::
size_t N>
1220template<
typename T, std::
size_t N>
1227template<
typename T,
typename... Args, Args... args>
1228inline constexpr format param_format(std::array<T, args...>
const &)
1230 return format::text;
1235template<
typename... Args, Args... args>
1236inline constexpr format param_format(std::array<std::byte, args...>
const &)
1238 return format::binary;
1242template<
typename T, std::
size_t N>
1249template<
typename T>
inline std::string to_string(T
const &value)
1253 "Attempt to convert null " + std::string{
type_name<T>} +
1260 auto const data{buf.data()};
1263 buf.resize(
static_cast<std::size_t
>(end - data - 1));
1268template<>
inline std::string to_string(
float const &value)
1272template<>
inline std::string to_string(
double const &value)
1276template<>
inline std::string to_string(
long double const &value)
1280template<>
inline std::string to_string(std::stringstream
const &value)
1286template<
typename T>
inline void into_string(T
const &value, std::string &out)
1290 "Attempt to convert null " +
type_name<T> +
" to a string."};
1295 auto const data{out.data()};
1298 out.resize(
static_cast<std::size_t
>(end - data - 1));
An SQL array received from the database.
Definition array.hxx:56
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38
Value conversion failed, e.g. when converting "Hello" to int.
Definition except.hxx:283
Could not convert value to string: not enough buffer space.
Definition except.hxx:313
Internal items for libpqxx' own use. Do not use these yourself.
Definition encodings.cxx:33
void PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data, std::byte buffer[])
Reconstitute binary data from its escaped version.
Definition util.cxx:165
void throw_null_conversion(std::string const &type)
Throw exception for attempt to convert SQL NULL to given type.
Definition strconv.cxx:264
constexpr 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:516
constexpr char number_to_digit(int i) noexcept
Convert a number in [0, 9] to its ASCII digit.
Definition conversions.hxx:27
constexpr bool cmp_less(LEFT lhs, RIGHT rhs) noexcept
Same as std::cmp_less, or a workaround where that's not available.
Definition util.hxx:65
constexpr int digit_to_number(char c) noexcept
Compute numeric value of given textual digit (assuming that it is a digit).
Definition conversions.hxx:34
void PQXX_LIBEXPORT esc_bin(bytes_view binary_data, char buffer[]) noexcept
Hex-escape binary data into a buffer.
Definition util.cxx:133
std::string to_string_float(T value)
Floating-point implementations for pqxx::to_string().
Definition strconv.cxx:677
constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_greater, or workaround if not available.
Definition util.hxx:87
std::string state_buffer_overrun(int have_bytes, int need_bytes)
Summarize buffer overrun.
Definition strconv.cxx:276
char * generic_into_buf(char *begin, char *end, T const &value)
Generic implementation for into_buf, on top of to_buf.
Definition conversions.hxx:95
constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_greater_equal, or workaround if not available.
Definition util.hxx:113
constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_less_equal, or workaround if not available.
Definition util.hxx:100
constexpr 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:525
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition strconv.hxx:80
std::vector< std::string_view > to_buf(char *here, char const *end, TYPE... value)
Convert multiple values to strings inside a single buffer.
Definition strconv.hxx:493
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition strconv.hxx:559
std::conditional< has_generic_bytes_char_traits, std::basic_string_view< std::byte >, std::basic_string_view< std::byte, byte_char_traits > >::type bytes_view
Type alias for a view of bytes.
Definition util.hxx:383
std::conditional< has_generic_bytes_char_traits, std::basic_string< std::byte >, std::basic_string< std::byte, byte_char_traits > >::type bytes
Type alias for a container containing bytes.
Definition util.hxx:373
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition strconv.hxx:555
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:526
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition types.hxx:80
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:515
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits<TYPE>::to_buf by calling into_buf.
Definition strconv.hxx:587
constexpr bool is_sql_array
Does this type translate to an SQL array?
Definition strconv.hxx:539
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:548
format
Format code: is data text or binary?
Definition types.hxx:70
String traits for SQL arrays.
Definition conversions.hxx:1036
Deliberately nonfunctional conversion traits for char types.
Definition conversions.hxx:77
String traits for builtin floating-point types.
Definition conversions.hxx:134
static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value)
Floating-point to_buf implemented in terms of to_string.
Definition strconv.cxx:609
String traits for builtin integral types (though not bool).
Definition conversions.hxx:113
Nullness traits describing a type which does not have a null value.
Definition strconv.hxx:113
static constexpr bool always_null
Technically, you could have an optional of an always-null type.
Definition conversions.hxx:276
static constexpr std::variant< T... > null()=delete
Traits describing a type's "null value," if any.
Definition strconv.hxx:91
static bool is_null(TYPE const &value)
Is value a null?
static TYPE null()
Return a null value.
static bool has_null
Does this type have a null value?
Definition strconv.hxx:93
static bool always_null
Is this type always null?
Definition strconv.hxx:96
static char * from_string(std::string_view)=delete
Don't allow conversion to this type since it breaks const-safety.
static void from_string(std::string_view)=delete
Don't allow conversion to this type.
static std::string_view from_string(std::string_view)=delete
Don't convert to this type; it has nowhere to store its contents.
static std::variant< T... > from_string(std::string_view)=delete
static zview from_string(std::string_view)=delete
Don't convert to this type; it has nowhere to store its contents.
Traits class for use in string conversions.
Definition strconv.hxx:154
static TYPE from_string(std::string_view text)
Parse a string representation of a TYPE value.
static std::size_t size_buffer(TYPE const &value) noexcept
Estimate how much buffer space is needed to represent value.
static zview to_buf(char *begin, char *end, TYPE const &value)
Return a string_view representing value, plus terminating zero.
static constexpr bool converts_to_string
Is conversion from TYPE to strings supported?
Definition strconv.hxx:159
static char * into_buf(char *begin, char *end, TYPE const &value)
Write value's string representation into buffer at begin.
static constexpr bool converts_from_string
Is conversion from string_view to TYPE supported?
Definition strconv.hxx:165