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>
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;
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)};
180 digits10(lims::max_digits10 - lims::min_exponent10)};
183 std::numeric_limits<T>::max_digits10 +
208template<>
inline constexpr bool is_unquoted_safe<short>{
true};
213template<>
inline constexpr bool is_unquoted_safe<unsigned short>{
true};
216template<>
inline constexpr bool is_unquoted_safe<int>{
true};
219template<>
inline constexpr bool is_unquoted_safe<unsigned>{
true};
222template<>
inline constexpr bool is_unquoted_safe<long>{
true};
226template<>
inline constexpr bool is_unquoted_safe<unsigned long>{
true};
230template<>
inline constexpr bool is_unquoted_safe<long long>{
true};
235template<>
inline constexpr bool is_unquoted_safe<unsigned long long>{
true};
238template<>
inline constexpr bool is_unquoted_safe<float>{
true};
241template<>
inline constexpr bool is_unquoted_safe<double>{
true};
245template<>
inline constexpr bool is_unquoted_safe<long double>{
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; }
269template<>
inline constexpr bool is_unquoted_safe<bool>{
true};
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);
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
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;
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)
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;
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;
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};
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
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
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;
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)
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)
713 return {begin,
static_cast<std::size_t
>(
stop - begin - 1)};
730 static std::size_t
size_buffer(std::stringstream
const &) =
delete;
732 static std::stringstream
from_string(std::string_view text)
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;
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;
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;
773 static constexpr bool is_null(std::monostate
const &)
noexcept
777 static constexpr std::monostate
null()
noexcept {
return {}; }
783 static constexpr bool has_null =
true;
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>
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>
846 static constexpr bool has_null =
true;
848 static constexpr bool is_null(std::shared_ptr<T>
const &
t)
noexcept
852 static constexpr std::shared_ptr<T>
null() {
return {}; }
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;
913template<binary DATA>
struct string_traits<
DATA>
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."};
965 static char *
into_buf(
char *begin,
char *end,
bytes const &value)
970 "Not enough buffer space to escape binary data."};
986template<>
inline constexpr format param_format(
bytes const &)
988 return format::binary;
1016 "Not enough buffer space to escape binary data."};
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)
1054 std::size_t
const budget{size_buffer(value)};
1057 "Not enough buffer space to convert array to string."};
1063 for (
auto const &
elt : value)
1067 s_null.copy(
here, std::size(s_null));
1068 here += std::size(s_null);
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) {
1128 return 3 + std::accumulate(
1129 std::begin(value), std::end(value), std::size_t{},
1130 [](std::size_t
acc, elt_type
const &
elt) {
1149template<
typename T,
typename...
Args>
1154template<
typename T,
typename...
Args>
1161template<
typename T,
typename...
Args>
1162inline constexpr format param_format(std::vector<T, Args...>
const &)
1164 return format::text;
1169template<
typename...
Args>
1170inline constexpr format param_format(std::vector<std::byte, Args...>
const &)
1172 return format::binary;
1179#if defined(PQXX_HAVE_SPAN) && __has_include(<span>)
1180template<
typename T,
size_t Extent>
1181struct nullness<std::
span<T, Extent>> : no_null<std::span<T, Extent>>
1185template<
typename T,
size_t Extent>
1186struct string_traits<std::
span<T, Extent>>
1187 : internal::array_string_traits<std::span<T, Extent>>
1191template<
typename T,
size_t Extent>
1192inline constexpr format param_format(std::span<T, Extent>
const &)
1194 return format::text;
1198template<
size_t Extent>
1199inline constexpr format param_format(std::span<std::byte, Extent>
const &)
1201 return format::binary;
1205template<
typename T,
size_t Extent>
1210template<
typename T, std::
size_t N>
1215template<
typename T, std::
size_t N>
1223inline constexpr format param_format(std::array<T, args...>
const &)
1225 return format::text;
1231inline constexpr format param_format(std::array<std::byte, args...>
const &)
1233 return format::binary;
1237template<
typename T, std::
size_t N>
1244template<
typename T>
inline std::string to_string(
T const &value)
1247 throw conversion_error{
1248 "Attempt to convert null " + std::string{
type_name<T>} +
1255 auto const data{
buf.data()};
1258 buf.resize(
static_cast<std::size_t
>(end - data - 1));
1263template<>
inline std::string to_string(
float const &value)
1267template<>
inline std::string to_string(
double const &value)
1271template<>
inline std::string to_string(
long double const &value)
1275template<>
inline std::string to_string(std::stringstream
const &value)
1281template<
typename T>
inline void into_string(
T const &value, std::string &
out)
1284 throw conversion_error{
1285 "Attempt to convert null " +
type_name<T> +
" to a string."};
1290 auto const data{
out.data()};
1293 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
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:166
void throw_null_conversion(std::string const &type)
Throw exception for attempt to convert SQL NULL to given type.
Definition strconv.cxx:248
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:134
std::string to_string_float(T value)
Floating-point implementations for pqxx::to_string().
Definition strconv.cxx:661
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:260
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::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
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
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:548
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition strconv.hxx:555
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:593
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 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