libpqxx  7.6.1
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_STRINGCONV
12 #define PQXX_H_STRINGCONV
13 
14 #include "pqxx/compiler-public.hxx"
15 
16 #include <algorithm>
17 #include <cstring>
18 #include <limits>
19 #include <sstream>
20 #include <stdexcept>
21 #include <typeinfo>
22 
23 #if __has_include(<charconv>)
24 # include <charconv>
25 #endif
26 
27 #if defined(PQXX_HAVE_RANGES) && __has_include(<ranges>)
28 # include <ranges>
29 #endif
30 
31 #include "pqxx/except.hxx"
32 #include "pqxx/util.hxx"
33 #include "pqxx/zview.hxx"
34 
35 
36 namespace pqxx::internal
37 {
39 PQXX_LIBEXPORT std::string demangle_type_name(char const[]);
40 } // namespace pqxx::internal
41 
42 
43 namespace pqxx
44 {
69 
71 
79 template<typename TYPE>
80 std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())};
81 
82 
84 
90 template<typename TYPE, typename ENABLE = void> struct nullness
91 {
93  static bool has_null;
94 
96  static bool always_null;
97 
99  static bool is_null(TYPE const &value);
100 
102 
107  [[nodiscard]] static TYPE null();
108 };
109 
110 
112 template<typename TYPE> struct no_null
113 {
115 
125  static constexpr bool has_null = false;
126 
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 
152 template<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 
202 template<typename ENUM>
203 struct nullness<ENUM, std::enable_if_t<std::is_enum_v<ENUM>>> : no_null<ENUM>
204 {};
205 } // namespace pqxx
206 
207 
208 namespace pqxx::internal
209 {
211 
220 template<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, static_cast<impl_type>(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, static_cast<impl_type>(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(static_cast<impl_type>(value));
244  }
245 };
246 } // namespace pqxx::internal
247 
248 
250 
261 #define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
262  template<> struct string_traits<ENUM> : pqxx::internal::enum_traits<ENUM> \
263  {}; \
264  template<> inline std::string const type_name<ENUM> { #ENUM }
265 
266 
267 namespace pqxx
268 {
270 
282 template<typename TYPE>
283 [[nodiscard]] inline TYPE from_string(std::string_view text)
284 {
286 }
287 
288 
290 
296 template<>
297 [[nodiscard]] inline std::string_view from_string(std::string_view text)
298 {
299  return text;
300 }
301 
302 
304 
311 template<typename T> inline void from_string(std::string_view text, T &value)
312 {
313  value = from_string<T>(text);
314 }
315 
316 
318 
323 template<typename TYPE> inline std::string to_string(TYPE const &value);
324 
325 
327 
334 template<typename... TYPE>
335 [[nodiscard]] inline std::vector<std::string_view>
336 to_buf(char *here, char const *end, TYPE... value)
337 {
338  return std::vector<std::string_view>{[&here, end](auto v) {
339  auto begin = here;
340  here = string_traits<decltype(v)>::into_buf(begin, end, v);
341  // Exclude the trailing zero out of the string_view.
342  auto len{static_cast<std::size_t>(here - begin) - 1};
343  return std::string_view{begin, len};
344  }(value)...};
345 }
346 
348 
351 template<typename TYPE>
352 inline void into_string(TYPE const &value, std::string &out);
353 
354 
356 template<typename TYPE>
357 [[nodiscard]] inline bool is_null(TYPE const &value) noexcept
358 {
359  return nullness<strip_t<TYPE>>::is_null(value);
360 }
361 
362 
364 
367 template<typename... TYPE>
368 [[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept
369 {
370  return (string_traits<strip_t<TYPE>>::size_buffer(value) + ...);
371 }
372 
373 
375 
381 template<typename TYPE> inline constexpr bool is_sql_array{false};
382 
383 
385 
397 template<typename TYPE> inline constexpr bool is_unquoted_safe{false};
398 
399 
401 template<typename T> inline constexpr char array_separator{','};
402 
403 
405 
412 template<typename TYPE> inline constexpr format param_format(TYPE const &)
413 {
414  return format::text;
415 }
416 
417 
418 #if defined(PQXX_HAVE_CONCEPTS)
419 
426 template<class TYPE>
427 concept binary = std::ranges::contiguous_range<TYPE> and
428  std::is_same_v<strip_t<value_type<TYPE>>, std::byte>;
429 #endif
430 
431 } // namespace pqxx
432 
433 
434 #include "pqxx/internal/conversions.hxx"
435 #endif
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition: strconv.hxx:397
std::string demangle_type_name(char const [])
Attempt to demangle std::type_info::name() to something human-readable.
Definition: strconv.cxx:223
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:39
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:507
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
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:357
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
static ENUM from_string(std::string_view text)
Definition: strconv.hxx:236
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:368
void into_string(TYPE const &value, std::string &out)
Convert a value to a readable string that PostgreSQL will understand.
constexpr bool is_sql_array
Does this type translate to an SQL array?
Definition: strconv.hxx:381
T from_string(field const &value)
Convert a field&#39;s value to type T.
Definition: field.hxx:490
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition: strconv.hxx:80
Helper class for defining enum conversions.
Definition: strconv.hxx:220
constexpr format param_format(TYPE const &)
What&#39;s the preferred format for passing non-null parameters of this type?
Definition: strconv.hxx:412
static bool always_null
Is this type always null?
Definition: strconv.hxx:96
std::underlying_type_t< ENUM > impl_type
Definition: strconv.hxx:222
static std::size_t size_buffer(ENUM const &value) noexcept
Definition: strconv.hxx:241
STL namespace.
static constexpr bool is_null(TYPE const &) noexcept
Does a given value correspond to an SQL null value?
Definition: strconv.hxx:138
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:112
format
Format code: is data text or binary?
Definition: types.hxx:76
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition: strconv.hxx:401
void from_string(std::string_view text, T &value)
Attempt to convert postgres-generated string to given built-in object.
Definition: strconv.hxx:311
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:90
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:336
static TYPE from_string(std::string_view text)
Parse a string representation of a TYPE value.
Definition: strconv.cxx:724
static bool has_null
Does this type have a null value?
Definition: strconv.hxx:93
Internal items for libpqxx&#39; own use. Do not use these yourself.
Definition: composite.hxx:73
Traits class for use in string conversions.
Definition: strconv.hxx:152
static constexpr zview to_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:226
static constexpr char * into_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:231