14 #if !defined(PQXX_HEADER_PRE)
15 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
30 #include <string_view>
31 #include <type_traits>
48 #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable
49 # define PQXX_UNREACHABLE std::unreachable()
51 # define PQXX_UNREACHABLE [[unlikely]] while (false)
71 using namespace std::literals;
78 template<
typename TO,
typename FROM>
80 check_cast(FROM value, std::string_view description,
sl loc = sl::current())
82 std::is_arithmetic_v<FROM> and std::is_arithmetic_v<TO> and
83 (std::is_integral_v<FROM> == std::is_integral_v<TO>))
87 if constexpr (std::is_same_v<FROM, bool>)
88 return static_cast<TO
>(value);
90 using to_limits = std::numeric_limits<TO>;
92 if constexpr (std::is_integral_v<FROM>)
96 if (std::cmp_less(value, to_limits::lowest()))
99 "Underflow casting {} from {} to {}: {}", value, name_type<FROM>(),
100 name_type<TO>(), description),
102 if (std::cmp_greater(value, (to_limits::max)()))
105 "Overflow casting {} from {} to {}: {}", value, name_type<FROM>(),
106 name_type<TO>(), description),
109 else if (std::isinf(value))
118 if (value < to_limits::lowest())
121 "Underflow casting {} from {} to {}: {}", value, name_type<FROM>(),
122 name_type<TO>(), description),
124 if (value > (to_limits::max)())
127 "Overflow casting {} from {} to {}: {}", value, name_type<FROM>(),
128 name_type<TO>(), description),
132 return static_cast<TO
>(value);
146 bool safe_libpq =
false;
155 bool safe_kerberos =
false;
177 static void assign(std::byte &a,
const std::byte &b) noexcept { a = b; }
178 static bool eq(std::byte a, std::byte b) {
return a == b; }
179 static bool lt(std::byte a, std::byte b) {
return a < b; }
181 static int compare(
const std::byte *a,
const std::byte *b, std::size_t size)
183 return std::memcmp(a, b, size);
193 static size_t length(
const std::byte *data);
196 find(
const std::byte *data, std::size_t size,
const std::byte &value)
198 return static_cast<const std::byte *
>(
199 std::memchr(data,
static_cast<int>(value), size));
203 move(std::byte *dest,
const std::byte *src, std::size_t size)
205 return static_cast<std::byte *
>(std::memmove(dest, src, size));
209 copy(std::byte *dest,
const std::byte *src, std::size_t size)
211 return static_cast<std::byte *
>(std::memcpy(dest, src, size));
215 assign(std::byte *dest, std::size_t size, std::byte value)
217 return static_cast<std::byte *
>(
218 std::memset(dest,
static_cast<int>(value), size));
224 static std::byte
to_char_type(int_type value) {
return std::byte(value); }
226 static int_type
to_int_type(std::byte value) {
return int_type(value); }
228 static bool eq_int_type(int_type a, int_type b) {
return a == b; }
240 using bytes = std::vector<std::byte>;
263 return std::as_bytes(
264 std::span<item_t const>{std::data(data), std::size(data)});
275 template<
char_sized CHAR,
typename SIZE>
278 return binary_cast(std::span<CHAR>{data, check_cast<std::size_t>(size)});
290 template<
typename... T>
291 [[maybe_unused, deprecated(
"Use [[maybe_unused]], std::ignore, etc.")]]
292 inline constexpr
void ignore_unused(T &&...) noexcept
306 template<
typename HAYSTACK,
typename NEEDLE>
307 inline bool str_contains(HAYSTACK
const &haystack, NEEDLE
const &needle)
309 std::same_as<HAYSTACK, std::string> or
310 std::same_as<HAYSTACK, std::string_view>)
313 return haystack.find(needle) != HAYSTACK::npos;
325 template<
typename SL>
326 concept c_source_location =
requires(SL
const loc) {
327 { loc.file_name() } -> std::convertible_to<char const *>;
328 { loc.function_name() } -> std::convertible_to<char const *>;
329 { loc.line() } -> std::convertible_to<std::uint_least32_t>;
330 { loc.column() } -> std::convertible_to<std::uint_least32_t>;
338 template<c_source_location LOC>
339 PQXX_PURE inline std::string source_loc(LOC
const &loc)
341 char const *
const file{loc.file_name()};
342 assert(file !=
nullptr);
344 char const *
const func{loc.function_name()};
345 unsigned const line{loc.line()}, column{loc.column()};
348 bool const have_func{func !=
nullptr and *func !=
'\0'}, have_line{line > 0},
349 have_column{column > 0};
351 if (have_func and have_line and have_column)
353 return std::format(
"{}:{}:{}: ({})", file, line, column, func);
355 else if (have_func and have_line)
357 return std::format(
"{}:{}: ({})", file, line, func);
359 else if (have_line and have_column)
361 return std::format(
"{}:{}:{}:", file, line, column);
382 using namespace std::literals;
401 int apps_major,
int apps_minor,
int apps_patch,
402 std::string_view apps_version);
411 template<std::
size_t N>
417 template<std::
size_t N>
418 inline constexpr
char const *
as_c_string(
char const (&str)[N]) noexcept
423 inline constexpr
char const *
as_c_string(std::string
const &str) noexcept
435 template<
typename CHAR>
inline constexpr
bool is_digit(CHAR c) noexcept
437 return (c >=
'0') and (c <=
'9');
456 [[nodiscard]] std::string
473 void const *old_guest, std::string_view old_class, std::string_view old_name,
474 void const *new_guest, std::string_view new_class,
475 std::string_view new_name);
483 void const *old_guest, std::string_view old_class, std::string_view old_name,
484 void const *new_guest, std::string_view new_class,
485 std::string_view new_name);
495 assert(std::cmp_less(
496 binary_bytes, (std::numeric_limits<std::size_t>::max)() / 2u));
497 return 2 + (2 * binary_bytes) + 1;
507 if (escaped_bytes < 2u) [[unlikely]]
510 return (escaped_bytes - 2) / 2;
529 inline void esc_bin(T &&binary_data, std::span<char> buffer) noexcept
541 unesc_bin(std::string_view escaped_data, std::span<std::byte> buffer,
sl loc);
553 template<
typename RETURN,
typename... ARGS>
554 std::tuple<ARGS...>
args_f(RETURN (&func)(ARGS...));
562 template<
typename RETURN,
typename... ARGS>
563 std::tuple<ARGS...>
args_f(std::function<RETURN(ARGS...)>
const &);
571 template<
typename CLASS,
typename RETURN,
typename... ARGS>
580 template<
typename CLASS,
typename RETURN,
typename... ARGS>
581 std::tuple<ARGS...>
member_args_f(RETURN (CLASS::*)(ARGS...)
const);
591 template<
typename CALLABLE>
597 template<
typename CALLABLE>
605 template<
typename... TYPES>
606 std::tuple<std::remove_cvref_t<TYPES>...>
611 template<
typename... TYPES>
622 [[unlikely]]
return '\b';
624 [[unlikely]]
return '\f';
667 [[maybe_unused]]
PQXX_COLD inline char const *
671 return std::data(buffer);
673 return "Unknown error; could not retrieve error string.";
692 [[maybe_unused]]
int err_num, [[maybe_unused]] std::span<char> buffer)
698 #if defined(PQXX_HAVE_STERROR_S) || defined(PQXX_HAVE_STRERROR_R)
699 # if defined(PQXX_HAVE_STRERROR_S)
700 auto const err_result{
701 strerror_s(std::data(buffer), std::size(buffer), err_num)};
703 auto const err_result{
704 strerror_r(err_num, std::data(buffer), std::size(buffer))};
709 return "(No error information available.)";
730 template<
bool terminate>
732 std::string_view src, std::span<char> dst, std::size_t dst_offset,
sl loc)
734 auto const sz{std::size(src)};
735 if (std::cmp_greater(
736 dst_offset + sz + std::size_t(terminate), std::size(dst)))
739 "Text copy exceeded buffer space: tried to copy {} bytes '{}' into a "
740 "buffer of {} bytes, at offset {}.",
741 sz, src, std::size(dst), dst_offset),
743 auto at{dst_offset + src.copy(std::data(dst) + dst_offset, sz)};
744 if constexpr (terminate)
Could not convert value to string: not enough buffer space.
Definition: except.hxx:638
Something is out of range, similar to std::out_of_range.
Definition: except.hxx:651
Placeholders for libpq declarations.
Definition: util.cxx:298
void pqfreemem(void const *ptr) noexcept
Wrapper for PQfreemem(), with C++ linkage.
Definition: util.cxx:299
Private namespace for libpqxx's internal use; do not access.
Definition: connection.cxx:333
constexpr PQXX_ZARGS char const * as_c_string(char const str[]) noexcept
Get a raw C string pointer.
Definition: util.hxx:406
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
std::tuple< ARGS... > args_f(RETURN(&func)(ARGS...))
Helper for determining a function's parameter types.
int check_libpqxx_version(int apps_major, int apps_minor, int apps_patch, std::string_view apps_version)
Check library binary version against application's expectations.
Definition: util.cxx:258
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
std::tuple< ARGS... > member_args_f(RETURN(CLASS::*)(ARGS...))
Helper for determining a member function's parameter types.
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:82
std::size_t copy_chars(std::string_view src, std::span< char > dst, std::size_t dst_offset, sl loc)
Copy text from src into buf at offset dst_offset.
Definition: util.hxx:731
decltype(strip_types(std::declval< TYPES... >())) strip_types_t
Take a tuple type and apply std::remove_cvref_t to its component types.
Definition: util.hxx:612
PQXX_COLD char const * make_strerror_rs_result(int err_result, std::span< char > buffer)
Helper for avoiding type trouble with strerror_r()/strerror_s().
Definition: util.hxx:668
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
decltype(args_f(std::declval< CALLABLE >())) args_t
A callable's parameter types, as a tuple.
Definition: util.hxx:598
constexpr bool is_digit(CHAR c) noexcept
A safer and more generic replacement for std::isdigit.
Definition: util.hxx:435
constexpr PQXX_PURE char unescape_char(char escaped) noexcept
Return original byte for escaped character.
Definition: util.hxx:617
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
PQXX_COLD char const * error_string([[maybe_unused]] int err_num, [[maybe_unused]] std::span< char > buffer)
Get error string for a given errno value.
Definition: util.hxx:691
void esc_bin(bytes_view binary_data, std::span< char > buffer) noexcept
Hex-escape binary data into a buffer.
Definition: util.cxx:159
std::tuple< std::remove_cvref_t< TYPES >... > strip_types(std::tuple< TYPES... > const &)
Apply std::remove_cvref_t to each of a tuple type's component types.
The home of all libpqxx classes, functions, templates, etc.
Definition: array.cxx:26
std::span< std::byte const > bytes_view
Type alias for a view of bytes.
Definition: types.hxx:188
std::source_location sl
Convenience alias for std::source_location. It's just too long.
Definition: types.hxx:38
bytes_view binary_cast(TYPE const &data)
Cast binary data to a type that libpqxx will recognise as binary.
Definition: util.hxx:260
std::remove_cvref_t< std::ranges::range_value_t< CONTAINER > > value_type
The type of a container's elements.
Definition: types.hxx:138
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
PQXX_LIBEXPORT thread_safety_model describe_thread_safety()
Describe thread safety available in this build.
Definition: util.cxx:35
unsigned int oid
PostgreSQL database row identifier.
Definition: types.hxx:73
std::string description
A human-readable description of any thread-safety issues.
Definition: util.hxx:143
TO check_cast(FROM value, std::string_view description, sl loc=sl::current()) requires(std
Cast a numeric value to another type, or throw if it underflows/overflows.
Definition: util.hxx:80
std::vector< std::byte > bytes
Type alias for a container containing bytes.
Definition: util.hxx:240
constexpr oid oid_none
The "null" oid.
Definition: util.hxx:283
format
Format code: is data text or binary?
Definition: types.hxx:121
Descriptor of library's thread-safety model.
Definition: util.hxx:141
Custom std::char_trast if the compiler does not provide one.
Definition: util.hxx:174
static PQXX_RETURNS_NONNULL std::byte * assign(std::byte *dest, std::size_t size, std::byte value)
Definition: util.hxx:215
static PQXX_RETURNS_NONNULL const std::byte * find(const std::byte *data, std::size_t size, const std::byte &value)
Definition: util.hxx:196
static PQXX_RETURNS_NONNULL std::byte * move(std::byte *dest, const std::byte *src, std::size_t size)
Definition: util.hxx:203
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:177
static std::byte to_char_type(int_type value)
Definition: util.hxx:224
static PQXX_RETURNS_NONNULL std::byte * copy(std::byte *dest, const std::byte *src, std::size_t size)
Definition: util.hxx:209
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:178
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:179
static int_type to_int_type(std::byte value)
Definition: util.hxx:226
static bool eq_int_type(int_type a, int_type b)
Definition: util.hxx:228
std::byte char_type
Definition: util.hxx:175
static int compare(const std::byte *a, const std::byte *b, std::size_t size)
Definition: util.hxx:181