libpqxx  7.4.1
strconv.hxx
1 /* String conversion definitions.
2  *
3  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
4  *
5  * Copyright (c) 2000-2021, 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 #include "pqxx/except.hxx"
28 #include "pqxx/util.hxx"
29 #include "pqxx/zview.hxx"
30 
31 
32 namespace pqxx::internal
33 {
35 PQXX_LIBEXPORT std::string demangle_type_name(char const[]);
36 } // namespace pqxx::internal
37 
38 
39 namespace pqxx
40 {
65 
67 
75 template<typename TYPE>
76 std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())};
77 
78 
80 
86 template<typename TYPE, typename ENABLE = void> struct nullness
87 {
89  static bool has_null;
90 
92  static bool always_null;
93 
95  static bool is_null(TYPE const &value);
96 
98 
103  [[nodiscard]] static TYPE null();
104 };
105 
106 
108 template<typename TYPE> struct no_null
109 {
111 
121  static constexpr bool has_null = false;
122 
124 
127  static constexpr bool always_null = false;
128 
130 
134  [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept
135  {
136  return false;
137  }
138 };
139 
140 
142 
148 template<typename TYPE> struct string_traits
149 {
151 
168  [[nodiscard]] static inline zview
169  to_buf(char *begin, char *end, TYPE const &value);
170 
172 
179  static inline char *into_buf(char *begin, char *end, TYPE const &value);
180 
182 
185  [[nodiscard]] static inline TYPE from_string(std::string_view text);
186 
188 
192  [[nodiscard]] static inline std::size_t
193  size_buffer(TYPE const &value) noexcept;
194 };
195 
196 
198 template<typename ENUM>
199 struct nullness<ENUM, std::enable_if_t<std::is_enum_v<ENUM>>> : no_null<ENUM>
200 {};
201 } // namespace pqxx
202 
203 
204 namespace pqxx::internal
205 {
207 
216 template<typename ENUM> struct enum_traits
217 {
218  using impl_type = std::underlying_type_t<ENUM>;
220 
221  [[nodiscard]] static constexpr zview
222  to_buf(char *begin, char *end, ENUM const &value)
223  {
224  return impl_traits::to_buf(begin, end, static_cast<impl_type>(value));
225  }
226 
227  static constexpr char *into_buf(char *begin, char *end, ENUM const &value)
228  {
229  return impl_traits::into_buf(begin, end, static_cast<impl_type>(value));
230  }
231 
232  [[nodiscard]] static ENUM from_string(std::string_view text)
233  {
234  return static_cast<ENUM>(impl_traits::from_string(text));
235  }
236 
237  [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept
238  {
239  return impl_traits::size_buffer(static_cast<impl_type>(value));
240  }
241 };
242 } // namespace pqxx::internal
243 
244 
246 
257 #define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
258  template<> struct string_traits<ENUM> : pqxx::internal::enum_traits<ENUM> \
259  {}; \
260  template<> inline std::string const type_name<ENUM> { #ENUM }
261 
262 
263 namespace pqxx
264 {
266 
278 template<typename TYPE>
279 [[nodiscard]] inline TYPE from_string(std::string_view text)
280 {
282 }
283 
284 
286 
292 template<>
293 [[nodiscard]] inline std::string_view from_string(std::string_view text)
294 {
295  return text;
296 }
297 
298 
300 
307 template<typename T> inline void from_string(std::string_view text, T &value)
308 {
309  value = from_string<T>(text);
310 }
311 
312 
314 
319 template<typename TYPE> inline std::string to_string(TYPE const &value);
320 
321 
323 
330 template<typename... TYPE>
331 [[nodiscard]] inline std::vector<std::string_view>
332 to_buf(char *here, char const *end, TYPE... value)
333 {
334  return std::vector<std::string_view>{[&here, end](auto v) {
335  auto begin = here;
336  here = string_traits<decltype(v)>::into_buf(begin, end, v);
337  // Exclude the trailing zero out of the string_view.
338  auto len{static_cast<std::size_t>(here - begin) - 1};
339  return std::string_view{begin, len};
340  }(value)...};
341 }
342 
344 
347 template<typename TYPE>
348 inline void into_string(TYPE const &value, std::string &out);
349 
350 
352 template<typename TYPE>
353 [[nodiscard]] inline bool is_null(TYPE const &value) noexcept
354 {
355  return nullness<TYPE>::is_null(value);
356 }
357 
358 
360 
363 template<typename... TYPE>
364 [[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept
365 {
366  return (string_traits<TYPE>::size_buffer(value) + ...);
367 }
368 
369 
371 
377 template<typename TYPE> inline constexpr bool is_sql_array{false};
378 
379 
381 
393 template<typename TYPE> inline constexpr bool is_unquoted_safe{false};
394 
395 
397 template<typename T> inline constexpr char array_separator{','};
399 } // namespace pqxx
400 
401 
402 #include "pqxx/internal/conversions.hxx"
403 #endif
static constexpr zview to_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:222
Traits class for use in string conversions.
Definition: strconv.hxx:148
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:353
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:364
static bool is_null(TYPE const &value)
Is value a null?
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition: strconv.hxx:393
static bool always_null
Is this type always null?
Definition: strconv.hxx:92
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:332
constexpr bool is_sql_array
Does this type translate to an SQL array?
Definition: strconv.hxx:377
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:503
static constexpr bool is_null(TYPE const &) noexcept
Does a given value correspond to an SQL null value?
Definition: strconv.hxx:134
Helper class for defining enum conversions.
Definition: strconv.hxx:216
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition: strconv.hxx:397
std::underlying_type_t< ENUM > impl_type
Definition: strconv.hxx:218
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition: strconv.hxx:76
void into_string(TYPE const &value, std::string &out)
Convert a value to a readable string that PostgreSQL will understand.
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:108
T from_string(field const &value)
Convert a field&#39;s value to type T.
Definition: field.hxx:491
static constexpr char * into_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:227
STL namespace.
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:86
static TYPE from_string(std::string_view text)
Parse a string representation of a TYPE value.
Definition: strconv.cxx:717
static std::size_t size_buffer(ENUM const &value) noexcept
Definition: strconv.hxx:237
void from_string(std::string_view text, T &value)
Attempt to convert postgres-generated string to given built-in object.
Definition: strconv.hxx:307
static ENUM from_string(std::string_view text)
Definition: strconv.hxx:232
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:37
static bool has_null
Does this type have a null value?
Definition: strconv.hxx:89
Internal items for libpqxx&#39; own use. Do not use these yourself.
Definition: composite.hxx:73
std::string demangle_type_name(char const [])
Attempt to demangle std::type_info::name() to something human-readable.
Definition: strconv.cxx:222