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 
47 // TODO: Probably better not to supply a default template.
49 
52 template<typename T> struct string_traits;
53 
54 namespace internal
55 {
57 [[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
58  const std::string &type);
59 } // namespace pqxx::internal
60 
61 
69 #define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T) \
70 template<> struct PQXX_LIBEXPORT string_traits<T> \
71 { \
72  static constexpr const char *name() noexcept { return #T; } \
73  static constexpr bool has_null() noexcept { return false; } \
74  static bool is_null(T) { return false; } \
75  [[noreturn]] static T null() \
76  { internal::throw_null_conversion(name()); } \
77  static void from_string(const char Str[], T &Obj); \
78  static std::string to_string(T Obj); \
79 };
80 
82 
91 
95 
96 #undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
97 
98 
100 
109 template<typename ENUM>
111 {
112  using underlying_type = typename std::underlying_type<ENUM>::type;
114 
115  static constexpr bool has_null() noexcept { return false; }
116  [[noreturn]] static ENUM null()
117  { internal::throw_null_conversion("enum type"); }
118 
119  static void from_string(const char Str[], ENUM &Obj)
120  {
121  underlying_type tmp;
123  Obj = ENUM(tmp);
124  }
125 
126  static std::string to_string(ENUM Obj)
128 };
129 
130 
132 
143 #define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
144 template<> \
145 struct PQXX_LIBEXPORT string_traits<ENUM> : pqxx::enum_traits<ENUM> \
146 { \
147  static constexpr const char *name() noexcept { return #ENUM; } \
148  [[noreturn]] static ENUM null() \
149  { internal::throw_null_conversion(name()); } \
150 }
151 
152 
154 template<> struct PQXX_LIBEXPORT string_traits<const char *>
155 {
156  static constexpr const char *name() noexcept { return "const char *"; }
157  static constexpr bool has_null() noexcept { return true; }
158  static bool is_null(const char *t) { return !t; }
159  static const char *null() { return nullptr; }
160  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
161  static std::string to_string(const char *Obj) { return Obj; }
162 };
163 
165 template<> struct PQXX_LIBEXPORT string_traits<char *>
166 {
167  static constexpr const char *name() noexcept { return "char *"; }
168  static constexpr bool has_null() noexcept { return true; }
169  static bool is_null(const char *t) { return !t; }
170  static const char *null() { return nullptr; }
171 
172  // Don't allow this conversion since it breaks const-safety.
173  // static void from_string(const char Str[], char *&Obj);
174 
175  static std::string to_string(char *Obj) { return Obj; }
176 };
177 
179 template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
180 {
181  static constexpr const char *name() noexcept { return "char[]"; }
182  static constexpr bool has_null() noexcept { return true; }
183  static bool is_null(const char t[]) { return !t; }
184  static const char *null() { return nullptr; }
185  static std::string to_string(const char Obj[]) { return Obj; }
186 };
187 
188 template<> struct PQXX_LIBEXPORT string_traits<std::string>
189 {
190  static constexpr const char *name() noexcept { return "string"; }
191  static constexpr bool has_null() noexcept { return false; }
192  static bool is_null(const std::string &) { return false; }
193  static std::string null()
194  { internal::throw_null_conversion(name()); return std::string(); }
195  static void from_string(const char Str[], std::string &Obj) { Obj=Str; }
196  static std::string to_string(const std::string &Obj) { return Obj; }
197 };
198 
199 template<> struct PQXX_LIBEXPORT string_traits<const std::string>
200 {
201  static constexpr const char *name() noexcept { return "const string"; }
202  static constexpr bool has_null() noexcept { return false; }
203  static bool is_null(const std::string &) { return false; }
204  static const std::string null()
205  { internal::throw_null_conversion(name()); return std::string(); }
206  static const std::string to_string(const std::string &Obj) { return Obj; }
207 };
208 
209 template<> struct PQXX_LIBEXPORT string_traits<std::stringstream>
210 {
211  static constexpr const char *name() noexcept { return "stringstream"; }
212  static constexpr bool has_null() noexcept { return false; }
213  static bool is_null(const std::stringstream &) { return false; }
214  static std::stringstream null()
215  {
217  // No, dear compiler, we don't need a return here.
218  throw 0;
219  }
220  static void from_string(const char Str[], std::stringstream &Obj)
221  { Obj.clear(); Obj << Str; }
222  static std::string to_string(const std::stringstream &Obj)
223  { return Obj.str(); }
224 };
225 
226 
227 // TODO: Implement date conversions
228 
230 
242 template<typename T>
243  inline void from_string(const char Str[], T &Obj)
244 {
245  if (!Str) throw std::runtime_error("Attempt to read null string");
247 }
248 
249 
251 
257 template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
258 {
259  return from_string(Str, Obj);
260 }
261 
262 template<>
263  inline void from_string<std::string>( //[t00]
264  const char Str[],
265  std::string &Obj,
266  size_t len)
267 {
268  if (!Str) throw std::runtime_error("Attempt to read null string");
269  Obj.assign(Str, len);
270 }
271 
272 template<typename T>
273  inline void from_string(const std::string &Str, T &Obj) //[t45]
274  { from_string(Str.c_str(), Obj); }
275 
276 template<typename T>
277  inline void from_string(const std::stringstream &Str, T &Obj) //[t00]
278  { from_string(Str.str(), Obj); }
279 
280 template<> inline void
281 from_string(const std::string &Str, std::string &Obj) //[t46]
282  { Obj = Str; }
283 
284 
285 namespace internal
286 {
288 inline int digit_to_number(char c) noexcept { return c-'0'; }
289 inline char number_to_digit(int i) noexcept
290  { return static_cast<char>(i+'0'); }
291 } // namespace pqxx::internal
292 
293 
295 
299 template<typename T> inline std::string to_string(const T &Obj)
300  { return string_traits<T>::to_string(Obj); }
301 
303 
304 } // namespace pqxx
305 
306 #endif
static bool is_null(const char *t)
Definition: strconv.hxx:158
static const char * null()
Definition: strconv.hxx:184
static const char * null()
Definition: strconv.hxx:170
static std::string to_string(const std::stringstream &Obj)
Definition: strconv.hxx:222
static const std::string to_string(const std::string &Obj)
Definition: strconv.hxx:206
#define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T)
Definition: strconv.hxx:69
static constexpr bool has_null() noexcept
Definition: strconv.hxx:202
static void from_string(const char Str[], std::stringstream &Obj)
Definition: strconv.hxx:220
static std::string to_string(const char Obj[])
Definition: strconv.hxx:185
static void from_string(const char Str[], ENUM &Obj)
Definition: strconv.hxx:119
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:434
void from_string(const field &F, T &Obj)
Convert a field&#39;s string contents to another type.
Definition: field.hxx:354
static constexpr bool has_null() noexcept
Definition: strconv.hxx:182
char number_to_digit(int i) noexcept
Definition: strconv.hxx:289
static constexpr const char * name() noexcept
Definition: strconv.hxx:181
static ENUM null()
Definition: strconv.hxx:116
int digit_to_number(char c) noexcept
Compute numeric value of given textual digit (assuming that it is a digit)
Definition: strconv.hxx:288
static bool is_null(const std::string &)
Definition: strconv.hxx:192
static constexpr bool has_null() noexcept
Definition: strconv.hxx:191
static const char * null()
Definition: strconv.hxx:159
static constexpr const char * name() noexcept
Definition: strconv.hxx:201
static bool is_null(const std::stringstream &)
Definition: strconv.hxx:213
void throw_null_conversion(const std::string &type)
Throw exception for attempt to convert null to given type.
Definition: strconv.cxx:291
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:22
static std::string to_string(const std::string &Obj)
Definition: strconv.hxx:196
static constexpr bool has_null() noexcept
Definition: strconv.hxx:212
static void from_string(const char Str[], std::string &Obj)
Definition: strconv.hxx:195
static constexpr const char * name() noexcept
Definition: strconv.hxx:167
Helper class for defining enum conversions.
Definition: strconv.hxx:110
static constexpr bool has_null() noexcept
Definition: strconv.hxx:115
static bool is_null(const std::string &)
Definition: strconv.hxx:203
static bool is_null(const char *t)
Definition: strconv.hxx:169
static constexpr const char * name() noexcept
Definition: strconv.hxx:156
static constexpr bool has_null() noexcept
Definition: strconv.hxx:168
STL namespace.
static constexpr const char * name() noexcept
Definition: strconv.hxx:211
static bool is_null(const char t[])
Definition: strconv.hxx:183
Traits class for use in string conversions.
Definition: strconv.hxx:52
static void from_string(const char Str[], const char *&Obj)
Definition: strconv.hxx:160
void from_string(const std::string &Str, std::string &Obj)
Definition: strconv.hxx:281
static std::string to_string(char *Obj)
Definition: strconv.hxx:175
static std::string null()
Definition: strconv.hxx:193
static std::string to_string(ENUM Obj)
Definition: strconv.hxx:126
static const std::string null()
Definition: strconv.hxx:204
static constexpr bool has_null() noexcept
Definition: strconv.hxx:157
static std::stringstream null()
Definition: strconv.hxx:214
static std::string to_string(const char *Obj)
Definition: strconv.hxx:161
static constexpr const char * name() noexcept
Definition: strconv.hxx:190
typename std::underlying_type< ENUM >::type underlying_type
Definition: strconv.hxx:112
std::string to_string(const T &Obj)
Convert built-in type to a readable string that PostgreSQL will understand.
Definition: strconv.hxx:299