libpqxx 7.7.5
strconv.hxx
1/* String conversion definitions.
2 *
3 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
4 *
5 * Copyright (c) 2000-2023, Jeroen T. Vermeulen.
6 *
7 * See COPYING for copyright license. If you did not receive a file called
8 * COPYING with this source code, please notify the distributor of this
9 * mistake, or contact the author.
10 */
11#ifndef PQXX_H_STRCONV
12#define PQXX_H_STRCONV
13
14#if !defined(PQXX_HEADER_PRE)
15# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
16#endif
17
18#include <algorithm>
19#include <cstring>
20#include <limits>
21#include <sstream>
22#include <stdexcept>
23#include <typeinfo>
24
25#if __has_include(<charconv>)
26# include <charconv>
27#endif
28
29#if defined(PQXX_HAVE_RANGES) && __has_include(<ranges>)
30# include <ranges>
31#endif
32
33#include "pqxx/except.hxx"
34#include "pqxx/util.hxx"
35#include "pqxx/zview.hxx"
36
37
38namespace pqxx::internal
39{
41PQXX_LIBEXPORT std::string demangle_type_name(char const[]);
42} // namespace pqxx::internal
43
44
45namespace pqxx
46{
71
73
81template<typename TYPE>
82std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())};
83
84
86
92template<typename TYPE, typename ENABLE = void> struct nullness
93{
95 static bool has_null;
96
98 static bool always_null;
99
101 static bool is_null(TYPE const &value);
102
104
109 [[nodiscard]] static TYPE null();
110};
111
112
114template<typename TYPE> struct no_null
115{
117
127 static constexpr bool has_null = false;
128
130
133 static constexpr bool always_null = false;
134
136
140 [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept
141 {
142 return false;
143 }
144};
145
146
148
154template<typename TYPE> struct string_traits
155{
157
174 [[nodiscard]] static inline zview
175 to_buf(char *begin, char *end, TYPE const &value);
176
178
185 static inline char *into_buf(char *begin, char *end, TYPE const &value);
186
188
191 [[nodiscard]] static inline TYPE from_string(std::string_view text);
192
193 // C++20: Can we make these all constexpr?
195
199 [[nodiscard]] static inline std::size_t
200 size_buffer(TYPE const &value) noexcept;
201};
202
203
205template<typename ENUM>
206struct nullness<ENUM, std::enable_if_t<std::is_enum_v<ENUM>>> : no_null<ENUM>
207{};
208} // namespace pqxx
209
210
211namespace pqxx::internal
212{
214
223template<typename ENUM> struct enum_traits
224{
225 using impl_type = std::underlying_type_t<ENUM>;
227
228 [[nodiscard]] static constexpr zview
229 to_buf(char *begin, char *end, ENUM const &value)
230 {
231 return impl_traits::to_buf(begin, end, to_underlying(value));
232 }
233
234 static constexpr char *into_buf(char *begin, char *end, ENUM const &value)
235 {
236 return impl_traits::into_buf(begin, end, to_underlying(value));
237 }
238
239 [[nodiscard]] static ENUM from_string(std::string_view text)
240 {
241 return static_cast<ENUM>(impl_traits::from_string(text));
242 }
243
244 [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept
245 {
246 return impl_traits::size_buffer(to_underlying(value));
247 }
248
249private:
250 // C++23: Replace with std::to_underlying.
251 static constexpr impl_type to_underlying(ENUM const &value) noexcept
252 {
253 return static_cast<impl_type>(value);
254 }
255};
256} // namespace pqxx::internal
257
258
260
271#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
272 template<> struct string_traits<ENUM> : pqxx::internal::enum_traits<ENUM> \
273 {}; \
274 template<> inline std::string const type_name<ENUM> \
275 { \
276# ENUM \
277 }
278
279
280namespace pqxx
281{
283
295template<typename TYPE>
296[[nodiscard]] inline TYPE from_string(std::string_view text)
297{
299}
300
301
303
309template<>
310[[nodiscard]] inline std::string_view from_string(std::string_view text)
311{
312 return text;
313}
314
315
317
324template<typename T> inline void from_string(std::string_view text, T &value)
325{
326 value = from_string<T>(text);
327}
328
329
331
336template<typename TYPE> inline std::string to_string(TYPE const &value);
337
338
340
347template<typename... TYPE>
348[[nodiscard]] inline std::vector<std::string_view>
349to_buf(char *here, char const *end, TYPE... value)
350{
351 return {[&here, end](auto v) {
352 auto begin = here;
353 here = string_traits<decltype(v)>::into_buf(begin, end, v);
354 // Exclude the trailing zero out of the string_view.
355 auto len{static_cast<std::size_t>(here - begin) - 1};
356 return std::string_view{begin, len};
357 }(value)...};
358}
359
361
364template<typename TYPE>
365inline void into_string(TYPE const &value, std::string &out);
366
367
369template<typename TYPE>
370[[nodiscard]] inline constexpr bool is_null(TYPE const &value) noexcept
371{
372 return nullness<strip_t<TYPE>>::is_null(value);
373}
374
375
377
380template<typename... TYPE>
381[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept
382{
383 return (string_traits<strip_t<TYPE>>::size_buffer(value) + ...);
384}
385
386
388
394template<typename TYPE> inline constexpr bool is_sql_array{false};
395
396
398
410template<typename TYPE> inline constexpr bool is_unquoted_safe{false};
411
412
414template<typename T> inline constexpr char array_separator{','};
415
416
418
425template<typename TYPE> inline constexpr format param_format(TYPE const &)
426{
427 return format::text;
428}
429
430
432
441template<typename TYPE>
442inline zview generic_to_buf(char *begin, char *end, TYPE const &value)
443{
444 using traits = string_traits<TYPE>;
445 // The trailing zero does not count towards the zview's size, so subtract 1
446 // from the result we get from into_buf().
447 if (is_null(value))
448 return {};
449 else
450 return {begin, traits::into_buf(begin, end, value) - begin - 1};
451}
452
453
454#if defined(PQXX_HAVE_CONCEPTS)
456
462template<class TYPE>
463concept binary = std::ranges::contiguous_range<TYPE> and
464 std::is_same_v<strip_t<value_type<TYPE>>, std::byte>;
465#endif
467} // namespace pqxx
468
469
470#include "pqxx/internal/conversions.hxx"
471#endif
The home of all libpqxx classes, functions, templates, etc.
Definition array.hxx:27
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition strconv.hxx:82
void into_string(TYPE const &value, std::string &out)
Convert a value to a readable string that PostgreSQL will understand.
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:349
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition strconv.hxx:414
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition strconv.hxx:410
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:381
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition types.hxx:91
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:370
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits<TYPE>::to_buf by calling into_buf.
Definition strconv.hxx:442
constexpr format param_format(TYPE const &)
What's the preferred format for passing non-null parameters of this type?
Definition strconv.hxx:425
constexpr bool is_sql_array
Does this type translate to an SQL array?
Definition strconv.hxx:394
std::string to_string(field const &value)
Convert a field to a string.
Definition result.cxx:533
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:506
format
Format code: is data text or binary?
Definition types.hxx:81
Internal items for libpqxx' own use. Do not use these yourself.
Definition composite.hxx:83
std::string demangle_type_name(char const[])
Attempt to demangle std::type_info::name() to something human-readable.
Definition strconv.cxx:230
Traits describing a type's "null value," if any.
Definition strconv.hxx:93
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:95
static bool always_null
Is this type always null?
Definition strconv.hxx:98
Nullness traits describing a type which does not have a null value.
Definition strconv.hxx:115
static constexpr bool always_null
Are all values of this type null?
Definition strconv.hxx:133
static constexpr bool has_null
Does TYPE have a "built-in null value"?
Definition strconv.hxx:127
static constexpr bool is_null(TYPE const &) noexcept
Does a given value correspond to an SQL null value?
Definition strconv.hxx:140
Traits class for use in string conversions.
Definition strconv.hxx:155
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 TYPE from_string(std::string_view text)
Parse a string representation of a TYPE value.
Definition strconv.cxx:744
static char * into_buf(char *begin, char *end, TYPE const &value)
Write value's string representation into buffer at begin.
Helper class for defining enum conversions.
Definition strconv.hxx:224
static std::size_t size_buffer(ENUM const &value) noexcept
Definition strconv.hxx:244
static constexpr zview to_buf(char *begin, char *end, ENUM const &value)
Definition strconv.hxx:229
std::underlying_type_t< ENUM > impl_type
Definition strconv.hxx:225
static ENUM from_string(std::string_view text)
Definition strconv.hxx:239
static constexpr char * into_buf(char *begin, char *end, ENUM const &value)
Definition strconv.hxx:234
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38