libpqxx
strconv.hxx
1 
11 #ifndef PQXX_H_STRINGCONV
12 #define PQXX_H_STRINGCONV
13 
14 #include "pqxx/compiler-public.hxx"
15 
16 #include <limits>
17 #include <sstream>
18 #include <stdexcept>
19 
20 
21 namespace pqxx
22 {
23 
46 
48 
51 template<typename T, typename = void> struct string_traits;
52 
53 namespace internal
54 {
56 [[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
57  const std::string &type);
58 
60 
67 template<typename TYPE> struct type_name;
68 #define PQXX_DECLARE_TYPE_NAME(TYPE) \
69  template<> struct type_name<TYPE> \
70  { static constexpr const char *value = #TYPE; }
71 
74 PQXX_DECLARE_TYPE_NAME(unsigned short);
76 PQXX_DECLARE_TYPE_NAME(unsigned int);
78 PQXX_DECLARE_TYPE_NAME(unsigned long);
79 PQXX_DECLARE_TYPE_NAME(long long);
80 PQXX_DECLARE_TYPE_NAME(unsigned long long);
83 PQXX_DECLARE_TYPE_NAME(long double);
85 PQXX_DECLARE_TYPE_NAME(const char *);
86 PQXX_DECLARE_TYPE_NAME(std::string);
87 PQXX_DECLARE_TYPE_NAME(const std::string);
88 PQXX_DECLARE_TYPE_NAME(std::stringstream);
89 #undef PQXX_DECLARE_TYPE_NAME
90 
91 template<size_t N> struct type_name<char[N]>
92 { static constexpr const char *value = "char[]"; };
93 
94 
96 
102 template<typename TYPE> struct PQXX_LIBEXPORT builtin_traits
103 {
104  static constexpr const char *name() noexcept
106  static constexpr bool has_null() noexcept { return false; }
107  static bool is_null(TYPE) { return false; }
108  [[noreturn]] static TYPE null() { throw_null_conversion(name()); }
109  static void from_string(const char Str[], TYPE &Obj);
110  static std::string to_string(TYPE Obj);
111 };
112 } // namespace pqxx::internal
113 
114 
116 #define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(TYPE) \
117  template<> struct PQXX_LIBEXPORT string_traits<TYPE> : \
118  internal::builtin_traits<TYPE> {};
119 
120 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)
121 
122 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
123 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
124 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
125 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
126 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
127 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
128 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
129 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)
130 
131 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
132 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
133 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)
134 
135 #undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
136 
137 
139 
148 template<typename ENUM>
150 {
151  using underlying_type = typename std::underlying_type<ENUM>::type;
153 
154  static constexpr bool has_null() noexcept { return false; }
155  [[noreturn]] static ENUM null()
156  { internal::throw_null_conversion("enum type"); }
157 
158  static void from_string(const char Str[], ENUM &Obj)
159  {
160  underlying_type tmp;
161  underlying_traits::from_string(Str, tmp);
162  Obj = ENUM(tmp);
163  }
164 
165  static std::string to_string(ENUM Obj)
166  { return underlying_traits::to_string(underlying_type(Obj)); }
167 };
168 
169 
171 
182 #define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
183 template<> \
184 struct string_traits<ENUM> : pqxx::enum_traits<ENUM> \
185 { \
186  static constexpr const char *name() noexcept { return #ENUM; } \
187  [[noreturn]] static ENUM null() \
188  { internal::throw_null_conversion(name()); } \
189 }
190 
191 
193 template<> struct PQXX_LIBEXPORT string_traits<const char *>
194 {
195  static constexpr const char *name() noexcept { return "const char *"; }
196  static constexpr bool has_null() noexcept { return true; }
197  static bool is_null(const char *t) { return t == nullptr; }
198  static const char *null() { return nullptr; }
199  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
200  static std::string to_string(const char *Obj) { return Obj; }
201 };
202 
204 template<> struct PQXX_LIBEXPORT string_traits<char *>
205 {
206  static constexpr const char *name() noexcept { return "char *"; }
207  static constexpr bool has_null() noexcept { return true; }
208  static bool is_null(const char *t) { return t == nullptr; }
209  static const char *null() { return nullptr; }
210 
211  // Don't allow this conversion since it breaks const-safety.
212  // static void from_string(const char Str[], char *&Obj);
213 
214  static std::string to_string(char *Obj) { return Obj; }
215 };
216 
218 template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
219 {
220  static constexpr const char *name() noexcept { return "char[]"; }
221  static constexpr bool has_null() noexcept { return true; }
222  static bool is_null(const char t[]) { return t == nullptr; }
223  static const char *null() { return nullptr; }
224  static std::string to_string(const char Obj[]) { return Obj; }
225 };
226 
227 template<> struct PQXX_LIBEXPORT string_traits<std::string>
228 {
229  static constexpr const char *name() noexcept { return "string"; }
230  static constexpr bool has_null() noexcept { return false; }
231  static bool is_null(const std::string &) { return false; }
232  [[noreturn]] static std::string null()
234  static void from_string(const char Str[], std::string &Obj) { Obj=Str; }
235  static std::string to_string(const std::string &Obj) { return Obj; }
236 };
237 
238 template<> struct PQXX_LIBEXPORT string_traits<const std::string>
239 {
240  static constexpr const char *name() noexcept { return "const string"; }
241  static constexpr bool has_null() noexcept { return false; }
242  static bool is_null(const std::string &) { return false; }
243  [[noreturn]] static const std::string null()
245  static const std::string to_string(const std::string &Obj) { return Obj; }
246 };
247 
248 template<> struct PQXX_LIBEXPORT string_traits<std::stringstream>
249 {
250  static constexpr const char *name() noexcept { return "stringstream"; }
251  static constexpr bool has_null() noexcept { return false; }
252  static bool is_null(const std::stringstream &) { return false; }
253  [[noreturn]] static std::stringstream null()
255  static void from_string(const char Str[], std::stringstream &Obj)
256  { Obj.clear(); Obj << Str; }
257  static std::string to_string(const std::stringstream &Obj)
258  { return Obj.str(); }
259 };
260 
261 
262 // TODO: Implement date conversions.
263 
265 
277 template<typename T>
278  inline void from_string(const char Str[], T &Obj)
279 {
280  if (Str == nullptr) throw std::runtime_error{"Attempt to read null string."};
282 }
283 
284 
286 
292 template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
293 {
294  return from_string(Str, Obj);
295 }
296 
297 template<>
298  inline void from_string<std::string>( //[t00]
299  const char Str[],
300  std::string &Obj,
301  size_t len)
302 {
303  if (Str == nullptr) throw std::runtime_error{"Attempt to read null string."};
304  Obj.assign(Str, len);
305 }
306 
307 template<typename T>
308  inline void from_string(const std::string &Str, T &Obj) //[t45]
309  { from_string(Str.c_str(), Obj); }
310 
311 template<typename T>
312  inline void from_string(const std::stringstream &Str, T &Obj) //[t00]
313  { from_string(Str.str(), Obj); }
314 
315 template<> inline void
316 from_string(const std::string &Str, std::string &Obj) //[t46]
317  { Obj = Str; }
318 
319 
320 namespace internal
321 {
323 constexpr int digit_to_number(char c) noexcept { return c-'0'; }
324 constexpr char number_to_digit(int i) noexcept
325  { return static_cast<char>(i+'0'); }
326 } // namespace pqxx::internal
327 
328 
330 
334 template<typename T> inline std::string to_string(const T &Obj)
335  { return string_traits<T>::to_string(Obj); }
336 
338 
339 } // namespace pqxx
340 
341 #endif
pqxx::connection_base::encoding_id
int encoding_id() const
Get the connection's encoding, as a PostgreSQL-defined code.
Definition: connection_base.cxx:1417
pqxx::string_traits< const char * >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:195
pqxx::string_traits< std::stringstream >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:251
pqxx::conversion_error
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:240
pqxx::transaction_base::exec
result exec(const std::string &Query, const std::string &Desc=std::string{})
Execute query.
Definition: transaction_base.cxx:249
pqxx::internal
Private namespace for libpqxx's internal use; do not access.
Definition: connection_base.hxx:43
pqxx::string_traits< std::stringstream >::from_string
static void from_string(const char Str[], std::stringstream &Obj)
Definition: strconv.hxx:255
pqxx::enum_traits::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:154
pqxx::cursor_base::accesspolicy
accesspolicy
Cursor access-pattern policy.
Definition: cursor.hxx:50
pqxx::string_traits< const char * >::is_null
static bool is_null(const char *t)
Definition: strconv.hxx:197
pqxx::cursor_base::forward_only
@ forward_only
Cursor can move forward only.
Definition: cursor.hxx:53
pqxx::internal::builtin_traits::to_string
static std::string to_string(TYPE Obj)
pqxx::string_traits< std::string >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:230
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:69
pqxx::from_string
void from_string(const field &F, T &Obj)
Convert a field's string contents to another type.
Definition: field.hxx:365
pqxx::string_traits< char * >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:207
pqxx::string_traits< std::stringstream >::is_null
static bool is_null(const std::stringstream &)
Definition: strconv.hxx:252
pqxx::cursor_base::all
static difference_type all() noexcept
Special value: read until end.
Definition: cursor.cxx:27
pqxx::string_traits< char * >::is_null
static bool is_null(const char *t)
Definition: strconv.hxx:208
pqxx::internal::type_name
Give a human-readable name for a type, at compile time.
Definition: strconv.hxx:67
pqxx::string_traits< const char * >::to_string
static std::string to_string(const char *Obj)
Definition: strconv.hxx:200
pqxx::string_traits< char * >::to_string
static std::string to_string(char *Obj)
Definition: strconv.hxx:214
pqxx::internal::enc_group
encoding_group enc_group(int libpq_enc_id)
Definition: encodings.cxx:637
pqxx::string_traits< std::string >::is_null
static bool is_null(const std::string &)
Definition: strconv.hxx:231
pqxx::string_traits< const std::string >::to_string
static const std::string to_string(const std::string &Obj)
Definition: strconv.hxx:245
pqxx::string_traits< char[N]>::is_null
static bool is_null(const char t[])
Definition: strconv.hxx:222
pqxx::transaction_base::quote_name
std::string quote_name(const std::string &identifier) const
Escape an SQL identifier for use in a query.
Definition: transaction_base.hxx:225
pqxx::cursor_base::updatepolicy
updatepolicy
Cursor update policy.
Definition: cursor.hxx:62
pqxx::string_traits< const std::string >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:240
pqxx::internal_error
Internal error in libpqxx library.
Definition: except.hxx:207
pqxx::enum_traits::underlying_type
typename std::underlying_type< ENUM >::type underlying_type
Definition: strconv.hxx:151
pqxx::internal::builtin_traits::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:106
pqxx::internal::number_to_digit
constexpr char number_to_digit(int i) noexcept
Definition: strconv.hxx:324
pqxx::string_traits< char[N]>::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:221
pqxx::enum_traits::to_string
static std::string to_string(ENUM Obj)
Definition: strconv.hxx:165
pqxx::string_traits< std::string >::from_string
static void from_string(const char Str[], std::string &Obj)
Definition: strconv.hxx:234
pqxx::string_traits< std::stringstream >::to_string
static std::string to_string(const std::stringstream &Obj)
Definition: strconv.hxx:257
pqxx::internal::builtin_traits::from_string
static void from_string(const char Str[], TYPE &Obj)
pqxx::enum_traits::from_string
static void from_string(const char Str[], ENUM &Obj)
Definition: strconv.hxx:158
pqxx::transaction_base::conn
connection_base & conn() const
Connection this transaction is running in.
Definition: transaction_base.hxx:492
pqxx::string_traits< const char * >::from_string
static void from_string(const char Str[], const char *&Obj)
Definition: strconv.hxx:199
pqxx::cursor_base::backward_all
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:35
pqxx::string_traits< std::stringstream >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:250
pqxx::string_traits< const std::string >::is_null
static bool is_null(const std::string &)
Definition: strconv.hxx:242
pqxx::internal::builtin_traits
Helper: string traits implementation for built-in types.
Definition: strconv.hxx:102
pqxx::string_traits< const std::string >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:241
pqxx::string_traits< char[N]>::to_string
static std::string to_string(const char Obj[])
Definition: strconv.hxx:224
pqxx::string_traits< char * >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:206
pqxx::cursor_base::difference_type
result_difference_type difference_type
Definition: cursor.hxx:44
pqxx::string_traits< std::string >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:229
pqxx::internal::builtin_traits::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:104
pqxx::to_string
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
pqxx::string_traits< char[N]>::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:220
pqxx::cursor_base
Common definitions for cursor types.
Definition: cursor.hxx:40
pqxx::cursor_base::owned
@ owned
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:92
pqxx::internal::builtin_traits::is_null
static bool is_null(TYPE)
Definition: strconv.hxx:107
pqxx::internal::digit_to_number
constexpr int digit_to_number(char c) noexcept
Compute numeric value of given textual digit (assuming that it is a digit)
Definition: strconv.hxx:323
pqxx::cursor_base::ownershippolicy
ownershippolicy
Cursor destruction policy.
Definition: cursor.hxx:89
pqxx::cursor_base::update
@ update
Cursor can be used to update data as well as read it.
Definition: cursor.hxx:67
pqxx::cursor_base::loose
@ loose
Leave SQL cursor in existence after close of object and transaction.
Definition: cursor.hxx:94
pqxx::string_traits< std::string >::to_string
static std::string to_string(const std::string &Obj)
Definition: strconv.hxx:235
pqxx::string_traits
Traits class for use in string conversions.
Definition: strconv.hxx:51
pqxx::transaction_base
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:136
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
pqxx::usage_error
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:218
pqxx::internal::PQXX_DECLARE_TYPE_NAME
PQXX_DECLARE_TYPE_NAME(bool)
pqxx::enum_traits
Helper class for defining enum conversions.
Definition: strconv.hxx:149
pqxx::string_traits< const char * >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:196
pqxx::internal::throw_null_conversion
void throw_null_conversion(const std::string &type)
Throw exception for attempt to convert null to given type.
Definition: strconv.cxx:58