libpqxx 7.7.0
strconv.hxx
1/* String conversion definitions.
2 *
3 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
4 *
5 * Copyright (c) 2000-2022, 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#include <algorithm>
15#include <cstring>
16#include <limits>
17#include <sstream>
18#include <stdexcept>
19#include <typeinfo>
20
21#if __has_include(<charconv>)
22# include <charconv>
23#endif
24
25#if defined(PQXX_HAVE_RANGES) && __has_include(<ranges>)
26# include <ranges>
27#endif
28
29#include "pqxx/except.hxx"
30#include "pqxx/util.hxx"
31#include "pqxx/zview.hxx"
32
33
34namespace pqxx::internal
35{
37PQXX_LIBEXPORT std::string demangle_type_name(char const[]);
38} // namespace pqxx::internal
39
40
41namespace pqxx
42{
67
69
77template<typename TYPE>
78std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())};
79
80
82
88template<typename TYPE, typename ENABLE = void> struct nullness
89{
91 static bool has_null;
92
94 static bool always_null;
95
97 static bool is_null(TYPE const &value);
98
100
105 [[nodiscard]] static TYPE null();
106};
107
108
110template<typename TYPE> struct no_null
111{
112 // C++20: constinit.
114
124 static constexpr bool has_null = false;
125
126 // C++20: constinit.
128
131 static constexpr bool always_null = false;
132
134
138 [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept
139 {
140 return false;
141 }
142};
143
144
146
152template<typename TYPE> struct string_traits
153{
155
172 [[nodiscard]] static inline zview
173 to_buf(char *begin, char *end, TYPE const &value);
174
176
183 static inline char *into_buf(char *begin, char *end, TYPE const &value);
184
186
189 [[nodiscard]] static inline TYPE from_string(std::string_view text);
190
192
196 [[nodiscard]] static inline std::size_t
197 size_buffer(TYPE const &value) noexcept;
198};
199
200
202template<typename ENUM>
203struct nullness<ENUM, std::enable_if_t<std::is_enum_v<ENUM>>> : no_null<ENUM>
204{};
205} // namespace pqxx
206
207
208namespace pqxx::internal
209{
211
220template<typename ENUM> struct enum_traits
221{
222 using impl_type = std::underlying_type_t<ENUM>;
224
225 [[nodiscard]] static constexpr zview
226 to_buf(char *begin, char *end, ENUM const &value)
227 {
228 return impl_traits::to_buf(begin, end, to_underlying(value));
229 }
230
231 static constexpr char *into_buf(char *begin, char *end, ENUM const &value)
232 {
233 return impl_traits::into_buf(begin, end, to_underlying(value));
234 }
235
236 [[nodiscard]] static ENUM from_string(std::string_view text)
237 {
238 return static_cast<ENUM>(impl_traits::from_string(text));
239 }
240
241 [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept
242 {
243 return impl_traits::size_buffer(to_underlying(value));
244 }
245
246private:
247 // C++23: Replace with std::to_underlying.
248 static impl_type to_underlying(ENUM const &value)
249 {
250 return static_cast<impl_type>(value);
251 }
252};
253} // namespace pqxx::internal
254
255
257
268#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
269 template<> struct string_traits<ENUM> : pqxx::internal::enum_traits<ENUM> \
270 {}; \
271 template<> inline std::string const type_name<ENUM> { #ENUM }
272
273
274namespace pqxx
275{
277
289template<typename TYPE>
290[[nodiscard]] inline TYPE from_string(std::string_view text)
291{
293}
294
295
297
303template<>
304[[nodiscard]] inline std::string_view from_string(std::string_view text)
305{
306 return text;
307}
308
309
311
318template<typename T> inline void from_string(std::string_view text, T &value)
319{
320 value = from_string<T>(text);
321}
322
323
325
330template<typename TYPE> inline std::string to_string(TYPE const &value);
331
332
334
341template<typename... TYPE>
342[[nodiscard]] inline std::vector<std::string_view>
343to_buf(char *here, char const *end, TYPE... value)
344{
345 return {[&here, end](auto v) {
346 auto begin = here;
347 here = string_traits<decltype(v)>::into_buf(begin, end, v);
348 // Exclude the trailing zero out of the string_view.
349 auto len{static_cast<std::size_t>(here - begin) - 1};
350 return std::string_view{begin, len};
351 }(value)...};
352}
353
355
358template<typename TYPE>
359inline void into_string(TYPE const &value, std::string &out);
360
361
363template<typename TYPE>
364[[nodiscard]] inline bool is_null(TYPE const &value) noexcept
365{
366 return nullness<strip_t<TYPE>>::is_null(value);
367}
368
369
371
374template<typename... TYPE>
375[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept
376{
377 return (string_traits<strip_t<TYPE>>::size_buffer(value) + ...);
378}
379
380
381// C++20: constinit.
383
389template<typename TYPE> inline constexpr bool is_sql_array{false};
390
391
392// C++20: constinit.
394
406template<typename TYPE> inline constexpr bool is_unquoted_safe{false};
407
408
409// C++20: constinit.
411template<typename T> inline constexpr char array_separator{','};
412
413
415
422template<typename TYPE> inline constexpr format param_format(TYPE const &)
423{
424 return format::text;
425}
426
427
429
438template<typename TYPE>
439inline zview generic_to_buf(char *begin, char *end, TYPE const &value)
440{
441 using traits = string_traits<TYPE>;
442 // The trailing zero does not count towards the zview's size, so subtract 1
443 // from the result we get from into_buf().
444 if (is_null(value))
445 return {};
446 else
447 return {begin, traits::into_buf(begin, end, value) - begin - 1};
448}
449
450
451#if defined(PQXX_HAVE_CONCEPTS)
453
459template<class TYPE>
460concept binary = std::ranges::contiguous_range<TYPE> and
461 std::is_same_v<strip_t<value_type<TYPE>>, std::byte>;
462#endif
464} // namespace pqxx
465
466
467#include "pqxx/internal/conversions.hxx"
468#endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:23
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition: strconv.hxx:78
void into_string(TYPE const &value, std::string &out)
Convert a value to a readable string that PostgreSQL will understand.
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition: types.hxx:87
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:343
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition: strconv.hxx:411
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition: strconv.hxx:406
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:375
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits<TYPE>::to_buf by calling into_buf.
Definition: strconv.hxx:439
constexpr format param_format(TYPE const &)
What's the preferred format for passing non-null parameters of this type?
Definition: strconv.hxx:422
constexpr bool is_sql_array
Does this type translate to an SQL array?
Definition: strconv.hxx:389
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:528
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:364
T from_string(field const &value)
Convert a field's value to type T.
Definition: field.hxx:494
format
Format code: is data text or binary?
Definition: types.hxx:77
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:80
std::string demangle_type_name(char const[])
Attempt to demangle std::type_info::name() to something human-readable.
Definition: strconv.cxx:229
Traits describing a type's "null value," if any.
Definition: strconv.hxx:89
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:91
static bool always_null
Is this type always null?
Definition: strconv.hxx:94
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:111
static constexpr bool always_null
Are all values of this type null?
Definition: strconv.hxx:131
static constexpr bool has_null
Does TYPE have a "built-in null value"?
Definition: strconv.hxx:124
static constexpr bool is_null(TYPE const &) noexcept
Does a given value correspond to an SQL null value?
Definition: strconv.hxx:138
Traits class for use in string conversions.
Definition: strconv.hxx:153
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:745
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:221
static std::size_t size_buffer(ENUM const &value) noexcept
Definition: strconv.hxx:241
static constexpr zview to_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:226
std::underlying_type_t< ENUM > impl_type
Definition: strconv.hxx:222
static ENUM from_string(std::string_view text)
Definition: strconv.hxx:236
static constexpr char * into_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:231
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:38