libpqxx  7.7.4
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 #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 
38 namespace pqxx::internal
39 {
41 PQXX_LIBEXPORT std::string demangle_type_name(char const[]);
42 } // namespace pqxx::internal
43 
44 
45 namespace pqxx
46 {
71 
73 
81 template<typename TYPE>
82 std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())};
83 
84 
86 
92 template<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 
114 template<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 
154 template<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 
205 template<typename ENUM>
206 struct nullness<ENUM, std::enable_if_t<std::is_enum_v<ENUM>>> : no_null<ENUM>
207 {};
208 } // namespace pqxx
209 
210 
211 namespace pqxx::internal
212 {
214 
223 template<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 
249 private:
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 
280 namespace pqxx
281 {
283 
295 template<typename TYPE>
296 [[nodiscard]] inline TYPE from_string(std::string_view text)
297 {
299 }
300 
301 
303 
309 template<>
310 [[nodiscard]] inline std::string_view from_string(std::string_view text)
311 {
312  return text;
313 }
314 
315 
317 
324 template<typename T> inline void from_string(std::string_view text, T &value)
325 {
326  value = from_string<T>(text);
327 }
328 
329 
331 
336 template<typename TYPE> inline std::string to_string(TYPE const &value);
337 
338 
340 
347 template<typename... TYPE>
348 [[nodiscard]] inline std::vector<std::string_view>
349 to_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 
364 template<typename TYPE>
365 inline void into_string(TYPE const &value, std::string &out);
366 
367 
369 template<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 
380 template<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 
394 template<typename TYPE> inline constexpr bool is_sql_array{false};
395 
396 
398 
410 template<typename TYPE> inline constexpr bool is_unquoted_safe{false};
411 
412 
414 template<typename T> inline constexpr char array_separator{','};
415 
416 
418 
425 template<typename TYPE> inline constexpr format param_format(TYPE const &)
426 {
427  return format::text;
428 }
429 
430 
432 
441 template<typename TYPE>
442 inline 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)
455 
462 template<class TYPE>
463 concept binary = std::ranges::contiguous_range<TYPE> and
464  std::is_same_v<strip_t<value_type<TYPE>>, std::byte>;
465 #endif
466 
467 } // namespace pqxx
468 
469 
470 #include "pqxx/internal/conversions.hxx"
471 #endif
static std::size_t size_buffer(ENUM const &value) noexcept
Definition: strconv.hxx:244
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
format
Format code: is data text or binary?
Definition: types.hxx:80
static constexpr bool is_null(TYPE const &) noexcept
Does a given value correspond to an SQL null value?
Definition: strconv.hxx:140
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition: strconv.hxx:82
Traits class for use in string conversions.
Definition: strconv.hxx:154
static bool always_null
Is this type always null?
Definition: strconv.hxx:98
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
static constexpr char * into_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:234
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
STL namespace.
Helper class for defining enum conversions.
Definition: strconv.hxx:223
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:114
static TYPE from_string(std::string_view text)
Parse a string representation of a TYPE value.
Definition: strconv.cxx:744
T from_string(field const &value)
Convert a field&#39;s value to type T.
Definition: field.hxx:506
static bool has_null
Does this type have a null value?
Definition: strconv.hxx:95
void from_string(std::string_view text, T &value)
Attempt to convert postgres-generated string to given built-in object.
Definition: strconv.hxx:324
constexpr format param_format(TYPE const &)
What&#39;s the preferred format for passing non-null parameters of this type?
Definition: strconv.hxx:425
static constexpr zview to_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:229
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
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
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:37
Internal items for libpqxx&#39; own use. Do not use these yourself.
Definition: composite.hxx:82
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition: strconv.hxx:410
static ENUM from_string(std::string_view text)
Definition: strconv.hxx:239
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::underlying_type_t< ENUM > impl_type
Definition: strconv.hxx:225
void into_string(TYPE const &value, std::string &out)
Convert a value to a readable string that PostgreSQL will understand.
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:92
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:370
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition: strconv.hxx:414
std::string demangle_type_name(char const [])
Attempt to demangle std::type_info::name() to something human-readable.
Definition: strconv.cxx:230