libpqxx  7.3.0
strconv.hxx
1 /* String conversion definitions.
2  *
3  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
4  *
5  * Copyright (c) 2000-2020, 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 {
110  static constexpr bool has_null = false;
111  static constexpr bool always_null = false;
112  [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept
113  {
114  return false;
115  }
116 };
117 
118 
120 
126 template<typename TYPE> struct string_traits
127 {
129 
146  [[nodiscard]] static inline zview
147  to_buf(char *begin, char *end, TYPE const &value);
148 
150 
157  static inline char *into_buf(char *begin, char *end, TYPE const &value);
158 
160 
163  [[nodiscard]] static inline TYPE from_string(std::string_view text);
164 
166 
170  [[nodiscard]] static inline std::size_t
171  size_buffer(TYPE const &value) noexcept;
172 };
173 
174 
176 template<typename ENUM>
177 struct nullness<ENUM, std::enable_if_t<std::is_enum_v<ENUM>>> : no_null<ENUM>
178 {};
179 } // namespace pqxx
180 
181 
182 namespace pqxx::internal
183 {
185 
194 template<typename ENUM> struct enum_traits
195 {
196  using impl_type = std::underlying_type_t<ENUM>;
198 
199  [[nodiscard]] static constexpr zview
200  to_buf(char *begin, char *end, ENUM const &value)
201  {
202  return impl_traits::to_buf(begin, end, static_cast<impl_type>(value));
203  }
204 
205  static constexpr char *into_buf(char *begin, char *end, ENUM const &value)
206  {
207  return impl_traits::into_buf(begin, end, static_cast<impl_type>(value));
208  }
209 
210  [[nodiscard]] static ENUM from_string(std::string_view text)
211  {
212  return static_cast<ENUM>(impl_traits::from_string(text));
213  }
214 
215  [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept
216  {
217  return impl_traits::size_buffer(static_cast<impl_type>(value));
218  }
219 };
220 } // namespace pqxx::internal
221 
222 
224 
235 #define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
236  template<> struct string_traits<ENUM> : pqxx::internal::enum_traits<ENUM> \
237  {}; \
238  template<> inline std::string const type_name<ENUM> { #ENUM }
239 
240 
241 namespace pqxx
242 {
244 
256 template<typename TYPE>
257 [[nodiscard]] inline TYPE from_string(std::string_view text)
258 {
260 }
261 
262 
264 
270 template<>
271 [[nodiscard]] inline std::string_view from_string(std::string_view text)
272 {
273  return text;
274 }
275 
276 
278 
285 template<typename T> inline void from_string(std::string_view text, T &value)
286 {
287  value = from_string<T>(text);
288 }
289 
290 
292 
297 template<typename TYPE> inline std::string to_string(TYPE const &value);
298 
299 
301 
308 template<typename... TYPE>
309 [[nodiscard]] inline std::vector<std::string_view>
310 to_buf(char *here, char const *end, TYPE... value)
311 {
312  return std::vector<std::string_view>{[&here, end](auto v) {
313  auto begin = here;
314  here = string_traits<decltype(v)>::into_buf(begin, end, v);
315  // Exclude the trailing zero out of the string_view.
316  auto len{static_cast<std::size_t>(here - begin) - 1};
317  return std::string_view{begin, len};
318  }(value)...};
319 }
320 
322 
325 template<typename TYPE>
326 inline void into_string(TYPE const &value, std::string &out);
327 
328 
330 template<typename TYPE>
331 [[nodiscard]] inline bool is_null(TYPE const &value) noexcept
332 {
333  return nullness<TYPE>::is_null(value);
334 }
335 
336 
338 
341 template<typename... TYPE>
342 [[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept
343 {
344  return (string_traits<TYPE>::size_buffer(value) + ...);
345 }
346 
347 
349 
355 template<typename TYPE> inline constexpr bool is_sql_array{false};
356 
357 
359 
371 template<typename TYPE> inline constexpr bool is_unquoted_safe{false};
372 
373 
375 template<typename T> inline constexpr char array_separator{','};
377 } // namespace pqxx
378 
379 
380 #include "pqxx/internal/conversions.hxx"
381 #endif
pqxx::internal::enum_traits::from_string
static ENUM from_string(std::string_view text)
Definition: strconv.hxx:210
pqxx::internal::demangle_type_name
std::string demangle_type_name(char const[])
Attempt to demangle std::type_info::name() to something human-readable.
Definition: strconv.cxx:222
pqxx::type_name
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition: strconv.hxx:76
pqxx::internal::to_string_float
std::string to_string_float(T value)
Floating-point implementations for pqxx::to_string().
Definition: strconv.cxx:639
pqxx::internal::enum_traits::impl_type
std::underlying_type_t< ENUM > impl_type
Definition: strconv.hxx:196
pqxx::nullness
Traits describing a type's "null value," if any.
Definition: strconv.hxx:87
pqxx::conversion_error
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:179
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
pqxx::internal::enum_traits::to_buf
static constexpr zview to_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:200
pqxx::is_null
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:331
pqxx::to_string
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:499
pqxx::internal::enc_group
encoding_group enc_group(int libpq_enc_id)
Definition: encodings.cxx:571
pqxx::internal::enum_traits
Helper class for defining enum conversions.
Definition: strconv.hxx:195
pqxx::internal::state_buffer_overrun
std::string state_buffer_overrun(int have_bytes, int need_bytes)
Definition: strconv.cxx:248
pqxx::internal::throw_null_conversion
void throw_null_conversion(std::string const &type)
Definition: strconv.cxx:242
pqxx::internal
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:74
pqxx::to_buf
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:310
pqxx::string_traits
Traits class for use in string conversions.
Definition: strconv.hxx:127
pqxx::string_traits::from_string
static TYPE from_string(std::string_view text)
Parse a string representation of a TYPE value.
Definition: strconv.cxx:717
pqxx::internal::enum_traits::size_buffer
static std::size_t size_buffer(ENUM const &value) noexcept
Definition: strconv.hxx:215
pqxx::into_string
void into_string(TYPE const &value, std::string &out)
Convert a value to a readable string that PostgreSQL will understand.
pqxx::nullness::has_null
static bool has_null
Does this type have a null value?
Definition: strconv.hxx:89
pqxx::no_null
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:109
pqxx::conversion_overrun
Could not convert value to string: not enough buffer space.
Definition: except.hxx:186
pqxx::nullness::always_null
static bool always_null
Is this type always null?
Definition: strconv.hxx:92
pqxx::no_null::always_null
static constexpr bool always_null
Definition: strconv.hxx:111
pqxx::array_separator
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition: strconv.hxx:375
pqxx::internal::to_dumb_stringstream
std::string to_dumb_stringstream(dumb_stringstream< F > &s, F value)
Definition: strconv.cxx:629
pqxx::nullness::is_null
static bool is_null(TYPE const &value)
Is value a null?
pqxx::from_string
T from_string(field const &value)
Convert a field's value to type T.
Definition: field.hxx:487
pqxx::no_null::is_null
static constexpr bool is_null(TYPE const &) noexcept
Definition: strconv.hxx:112
pqxx::is_sql_array
constexpr bool is_sql_array
Does this type translate to an SQL array?
Definition: strconv.hxx:355
pqxx::size_buffer
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:342
pqxx::no_null::has_null
static constexpr bool has_null
Definition: strconv.hxx:110
pqxx::string_traits::into_buf
static char * into_buf(char *begin, char *end, TYPE const &value)
Write value's string representation into buffer at begin.
pqxx::zview
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:38
pqxx::string_traits::to_buf
static zview to_buf(char *begin, char *end, TYPE const &value)
Return a string_view representing value, plus terminating zero.
pqxx::cursor_base::difference_type
result_difference_type difference_type
Definition: cursor.hxx:44
pqxx::internal::enum_traits::into_buf
static constexpr char * into_buf(char *begin, char *end, ENUM const &value)
Definition: strconv.hxx:205
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:71
pqxx::string_traits::size_buffer
static std::size_t size_buffer(TYPE const &value) noexcept
Estimate how much buffer space is needed to represent value.
pqxx::is_unquoted_safe
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition: strconv.hxx:371