14 #if !defined(PQXX_HEADER_PRE)
15 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
29 #include <string_view>
30 #include <type_traits>
35 #include "pqxx/except.hxx"
36 #include "pqxx/types.hxx"
37 #include "pqxx/version.hxx"
44 #include <pqxx/internal/libpq-forward.hxx>
48 #if defined(PQXX_HAVE_UNREACHABLE)
50 # define PQXX_UNREACHABLE std::unreachable()
52 # define PQXX_UNREACHABLE assert(false)
62 template<
typename LEFT,
typename RIGHT>
63 inline constexpr
bool cmp_less(LEFT lhs, RIGHT rhs) noexcept
65 #if defined(PQXX_HAVE_CMP)
66 return std::cmp_less(lhs, rhs);
71 constexpr
bool left_signed{std::is_signed_v<LEFT>};
72 if constexpr (left_signed == std::is_signed_v<RIGHT>)
74 else if constexpr (std::is_signed_v<LEFT>)
75 return (lhs <= 0) ? true : (std::make_unsigned_t<LEFT>(lhs) < rhs);
77 return (rhs <= 0) ? false : (lhs < std::make_unsigned_t<RIGHT>(rhs));
84 template<
typename LEFT,
typename RIGHT>
85 inline constexpr
bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept
87 #if defined(PQXX_HAVE_CMP)
88 return std::cmp_greater(lhs, rhs);
97 template<
typename LEFT,
typename RIGHT>
100 #if defined(PQXX_HAVE_CMP)
101 return std::cmp_less_equal(lhs, rhs);
110 template<
typename LEFT,
typename RIGHT>
113 #if defined(PQXX_HAVE_CMP)
114 return std::cmp_greater_equal(lhs, rhs);
125 [[nodiscard]]
inline std::string
cat2(std::string_view x, std::string_view y)
128 auto const xs{std::size(x)}, ys{std::size(y)};
130 x.copy(std::data(buf), xs);
131 y.copy(std::data(buf) + xs, ys);
139 using namespace std::literals;
142 template<
typename... T>
inline constexpr
void ignore_unused(T &&...) noexcept
150 template<
typename TO,
typename FROM>
151 inline TO
check_cast(FROM value, std::string_view description)
153 static_assert(std::is_arithmetic_v<FROM>);
154 static_assert(std::is_arithmetic_v<TO>);
155 static_assert(std::is_integral_v<FROM> == std::is_integral_v<TO>);
159 if constexpr (std::is_same_v<FROM, bool>)
160 return static_cast<TO
>(value);
166 using from_limits = std::numeric_limits<decltype(value)>;
167 using to_limits = std::numeric_limits<TO>;
168 if constexpr (std::is_signed_v<FROM>)
170 if constexpr (std::is_signed_v<TO>)
172 if (value < to_limits::lowest())
182 "Casting negative value to unsigned type: "sv, description)};
191 if constexpr (std::is_integral_v<FROM>)
193 using unsigned_from = std::make_unsigned_t<FROM>;
194 using unsigned_to = std::make_unsigned_t<TO>;
195 constexpr
auto from_max{
static_cast<unsigned_from
>((from_limits::max)())};
196 constexpr
auto to_max{
static_cast<unsigned_to
>((to_limits::max)())};
197 if constexpr (from_max > to_max)
203 else if constexpr ((from_limits::max)() > (to_limits::max)())
205 if (value > (to_limits::max)())
209 return static_cast<TO
>(value);
257 bool safe_libpq =
false;
266 bool safe_kerberos =
false;
277 #if defined(PQXX_HAVE_CONCEPTS)
278 # define PQXX_POTENTIAL_BINARY_ARG pqxx::potential_binary
280 # define PQXX_POTENTIAL_BINARY_ARG typename
292 static void assign(std::byte &a,
const std::byte &b) noexcept { a = b; }
293 static bool eq(std::byte a, std::byte b) {
return a == b; }
294 static bool lt(std::byte a, std::byte b) {
return a < b; }
296 static int compare(
const std::byte *a,
const std::byte *b, std::size_t size)
298 return std::memcmp(a, b, size);
308 static size_t length(
const std::byte *data);
310 static const std::byte *
311 find(
const std::byte *data, std::size_t size,
const std::byte &value)
313 return static_cast<const std::byte *
>(
314 std::memchr(data,
static_cast<int>(value), size));
318 move(std::byte *dest,
const std::byte *src, std::size_t size)
320 return static_cast<std::byte *
>(std::memmove(dest, src, size));
324 copy(std::byte *dest,
const std::byte *src, std::size_t size)
326 return static_cast<std::byte *
>(std::memcpy(dest, src, size));
329 static std::byte *
assign(std::byte *dest, std::size_t size, std::byte value)
331 return static_cast<std::byte *
>(
332 std::memset(dest,
static_cast<int>(value), size));
338 static std::byte
to_char_type(int_type value) {
return std::byte(value); }
340 static int_type
to_int_type(std::byte value) {
return int_type(value); }
342 static bool eq_int_type(int_type a, int_type b) {
return a == b; }
348 template<
typename TYPE,
typename =
void>
352 template<
typename TYPE>
354 TYPE, std::void_t<decltype(std::char_traits<TYPE>::eof)>> : std::true_type
363 #include "pqxx/internal/ignore-deprecated-pre.hxx"
373 std::basic_string<std::byte, byte_char_traits>>::type;
383 std::basic_string_view<std::byte, byte_char_traits>>::type;
385 #include "pqxx/internal/ignore-deprecated-post.hxx"
406 template<PQXX_POTENTIAL_BINARY_ARG TYPE>
412 reinterpret_cast<std::byte
const *
>(
413 const_cast<strip_t<decltype(*std::data(data))
> const *>(
419 #if defined(PQXX_HAVE_CONCEPTS)
420 template<
typename CHAR>
421 concept char_sized = (
sizeof(CHAR) == 1);
422 # define PQXX_CHAR_SIZED_ARG char_sized
424 # define PQXX_CHAR_SIZED_ARG typename
434 template<PQXX_CHAR_SIZED_ARG CHAR,
typename SIZE>
437 static_assert(
sizeof(CHAR) == 1);
439 reinterpret_cast<std::byte
const *
>(data),
440 check_cast<std::size_t>(size,
"binary data size")};
461 using namespace std::literals;
469 template<
typename CHAR>
inline constexpr
bool is_digit(CHAR c) noexcept
471 return (c >=
'0') and (c <=
'9');
478 [[nodiscard]] std::string
495 void const *old_guest, std::string_view old_class, std::string_view old_name,
496 void const *new_guest, std::string_view new_class,
497 std::string_view new_name);
505 void const *old_guest, std::string_view old_class, std::string_view old_name,
506 void const *new_guest, std::string_view new_class,
507 std::string_view new_name);
514 inline constexpr std::size_t
size_esc_bin(std::size_t binary_bytes) noexcept
516 return 2 + (2 * binary_bytes) + 1;
525 return (escaped_bytes - 2) / 2;
545 unesc_bin(std::string_view escaped_data, std::byte buffer[]);
553 template<
typename T>
auto ssize(T
const &c)
555 #if defined(PQXX_HAVE_SSIZE)
556 return std::ssize(c);
558 using signed_t = std::make_signed_t<decltype(std::size(c))>;
559 return static_cast<signed_t
>(std::size(c));
569 template<
typename RETURN,
typename... ARGS>
570 std::tuple<ARGS...>
args_f(RETURN (&func)(ARGS...));
578 template<
typename RETURN,
typename... ARGS>
579 std::tuple<ARGS...>
args_f(std::function<RETURN(ARGS...)>
const &);
587 template<
typename CLASS,
typename RETURN,
typename... ARGS>
596 template<
typename CLASS,
typename RETURN,
typename... ARGS>
597 std::tuple<ARGS...>
member_args_f(RETURN (CLASS::*)(ARGS...)
const);
607 template<
typename CALLABLE>
613 template<
typename CALLABLE>
621 template<
typename... TYPES>
622 std::tuple<strip_t<TYPES>...>
strip_types(std::tuple<TYPES...>
const &);
626 template<
typename... TYPES>
636 PQXX_UNLIKELY
return '\b';
638 PQXX_UNLIKELY
return '\f';
656 template<std::
size_t BYTES>
657 char const *PQXX_COLD
663 #if defined(PQXX_HAVE_STERROR_S) || defined(PQXX_HAVE_STRERROR_R)
664 # if defined(PQXX_HAVE_STRERROR_S)
665 auto const err_result{strerror_s(std::data(buffer), BYTES, err_num)};
667 auto const err_result{strerror_r(err_num, std::data(buffer), BYTES)};
669 if constexpr (std::is_same_v<
pqxx::strip_t<decltype(err_result)>,
char *>)
681 return std::data(buffer);
683 return "Compound errors.";
689 return "(No error information available.)";
698 PQXX_LIBEXPORT
void pqfreemem(
void const *) noexcept;
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:33
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition: types.hxx:78
bytes_view binary_cast(TYPE const &data)
Cast binary data to a type that libpqxx will recognise as binary.
Definition: util.hxx:407
strip_t< decltype(*std::begin(std::declval< CONTAINER >()))> value_type
The type of a container's elements.
Definition: types.hxx:94
void check_version() noexcept
Definition: util.hxx:234
thread_safety_model describe_thread_safety()
Describe thread safety available in this build.
Definition: util.cxx:35
constexpr void ignore_unused(T &&...) noexcept
Suppress compiler warning about an unused item.
Definition: util.hxx:142
constexpr bool has_generic_bytes_char_traits
Definition: util.hxx:357
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::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
constexpr oid oid_none
The "null" oid.
Definition: util.hxx:445
TO check_cast(FROM value, std::string_view description)
Cast a numeric value to another type, or throw if it underflows/overflows.
Definition: util.hxx:151
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:84
void unesc_bin(std::string_view escaped_data, std::byte buffer[])
Reconstitute binary data from its escaped version.
Definition: util.cxx:165
int PQXX_VERSION_CHECK() noexcept
Library version check stub.
Definition: version.cxx:23
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:514
std::tuple< strip_t< TYPES >... > strip_types(std::tuple< TYPES... > const &)
Helper: Apply strip_t to each of a tuple type's component types.
std::tuple< ARGS... > args_f(RETURN(&func)(ARGS...))
Helper for determining a function's parameter types.
char const *PQXX_COLD error_string(int err_num, std::array< char, BYTES > &buffer)
Get error string for a given errno value.
Definition: util.hxx:658
std::tuple< ARGS... > member_args_f(RETURN(CLASS::*)(ARGS...))
Helper for determining a member function's parameter types.
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:63
void check_unique_unregister(void const *old_guest, std::string_view old_class, std::string_view old_name, void const *new_guest, std::string_view new_class, std::string_view new_name)
Like check_unique_register, but for un-registering a guest.
Definition: util.cxx:80
void esc_bin(bytes_view binary_data, char buffer[]) noexcept
Hex-escape binary data into a buffer.
Definition: util.cxx:133
decltype(strip_types(std::declval< TYPES... >())) strip_types_t
Take a tuple type and apply strip_t to its component types.
Definition: util.hxx:627
void check_unique_register(void const *old_guest, std::string_view old_class, std::string_view old_name, void const *new_guest, std::string_view new_class, std::string_view new_name)
Check validity of registering a new "guest" in a "host.".
Definition: util.cxx:63
std::string describe_object(std::string_view class_name, std::string_view name)
Describe an object for humans, based on class name and optional name.
Definition: util.cxx:53
constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_greater, or workaround if not available.
Definition: util.hxx:85
decltype(args_f(std::declval< CALLABLE >())) args_t
A callable's parameter types, as a tuple.
Definition: util.hxx:614
constexpr bool is_digit(CHAR c) noexcept
A safer and more generic replacement for std::isdigit.
Definition: util.hxx:469
constexpr char unescape_char(char escaped) noexcept
Return original byte for escaped character.
Definition: util.hxx:631
constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_greater_equal, or workaround if not available.
Definition: util.hxx:111
std::string cat2(std::string_view x, std::string_view y)
Efficiently concatenate two strings.
Definition: util.hxx:125
constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_less_equal, or workaround if not available.
Definition: util.hxx:98
auto ssize(T const &c)
Transitional: std::ssize(), or custom implementation if not available.
Definition: util.hxx:553
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:523
void pqfreemem(void const *) noexcept
Wrapper for PQfreemem(), with C++ linkage.
Definition: util.cxx:205
Something is out of range, similar to std::out_of_range.
Definition: except.hxx:326
Descriptor of library's thread-safety model.
Definition: util.hxx:255
std::string description
A human-readable description of any thread-safety issues.
Definition: util.hxx:269
Custom std::char_trast if the compiler does not provide one.
Definition: util.hxx:289
static size_t length(const std::byte *data)
Deliberately undefined: "guess" the length of an array of bytes.
static void assign(std::byte &a, const std::byte &b) noexcept
Definition: util.hxx:292
static std::byte * move(std::byte *dest, const std::byte *src, std::size_t size)
Definition: util.hxx:318
static std::byte to_char_type(int_type value)
Definition: util.hxx:338
static int_type not_eof(int_type value)
Declared but not defined: makes no sense for binary data.
static bool eq(std::byte a, std::byte b)
Definition: util.hxx:293
static int_type eof()
Declared but not defined: makes no sense for binary data.
static bool lt(std::byte a, std::byte b)
Definition: util.hxx:294
static std::byte * assign(std::byte *dest, std::size_t size, std::byte value)
Definition: util.hxx:329
static int_type to_int_type(std::byte value)
Definition: util.hxx:340
static bool eq_int_type(int_type a, int_type b)
Definition: util.hxx:342
static const std::byte * find(const std::byte *data, std::size_t size, const std::byte &value)
Definition: util.hxx:311
std::byte char_type
Definition: util.hxx:290
static int compare(const std::byte *a, const std::byte *b, std::size_t size)
Definition: util.hxx:296
static std::byte * copy(std::byte *dest, const std::byte *src, std::size_t size)
Definition: util.hxx:324