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
21namespace pqxx
22{
23
46
48
51template<typename T, typename = void> struct string_traits;
52
53namespace internal
54{
56[[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
57 const std::string &type);
58
60
67template<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
74PQXX_DECLARE_TYPE_NAME(unsigned short);
80PQXX_DECLARE_TYPE_NAME(unsigned long long);
87PQXX_DECLARE_TYPE_NAME(const std::string);
88PQXX_DECLARE_TYPE_NAME(std::stringstream);
89#undef PQXX_DECLARE_TYPE_NAME
90
91template<size_t N> struct type_name<char[N]>
92{ static constexpr const char *value = "char[]"; };
93
94
96
102template<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
120PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)
121
122PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
123PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
124PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
125PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
126PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
127PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
128PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
129PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)
130
131PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
132PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
133PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)
134
135#undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
136
137
139
148template<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) \
183template<> \
184struct 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
193template<> 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
204template<> 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
218template<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
227template<> 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
238template<> 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
248template<> 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
277template<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
292template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
293{
294 return from_string(Str, Obj);
295}
296
297template<>
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
307template<typename T>
308 inline void from_string(const std::string &Str, T &Obj) //[t45]
309 { from_string(Str.c_str(), Obj); }
310
311template<typename T>
312 inline void from_string(const std::stringstream &Str, T &Obj) //[t00]
313 { from_string(Str.str(), Obj); }
314
315template<> inline void
316from_string(const std::string &Str, std::string &Obj) //[t46]
317 { Obj = Str; }
318
319
320namespace internal
321{
323constexpr int digit_to_number(char c) noexcept { return c-'0'; }
324constexpr char number_to_digit(int i) noexcept
325 { return static_cast<char>(i+'0'); }
326} // namespace pqxx::internal
327
328
330
334template<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
STL namespace.
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
void from_string(const field &F, T &Obj)
Convert a field's string contents to another type.
Definition: field.hxx:365
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
PQXX_DECLARE_TYPE_NAME(bool)
constexpr char number_to_digit(int i) noexcept
Definition: strconv.hxx:324
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
void throw_null_conversion(const std::string &type)
Throw exception for attempt to convert null to given type.
Definition: strconv.cxx:58
Traits class for use in string conversions.
Definition: strconv.hxx:51
Give a human-readable name for a type, at compile time.
Definition: strconv.hxx:67
Helper: string traits implementation for built-in types.
Definition: strconv.hxx:103
static void from_string(const char Str[], TYPE &Obj)
static bool is_null(TYPE)
Definition: strconv.hxx:107
static std::string to_string(TYPE Obj)
static TYPE null()
Definition: strconv.hxx:108
static constexpr const char * name() noexcept
Definition: strconv.hxx:104
static constexpr bool has_null() noexcept
Definition: strconv.hxx:106
Helper class for defining enum conversions.
Definition: strconv.hxx:150
static std::string to_string(ENUM Obj)
Definition: strconv.hxx:165
static ENUM null()
Definition: strconv.hxx:155
static constexpr bool has_null() noexcept
Definition: strconv.hxx:154
static void from_string(const char Str[], ENUM &Obj)
Definition: strconv.hxx:158
typename std::underlying_type< ENUM >::type underlying_type
Definition: strconv.hxx:151
static const char * null()
Definition: strconv.hxx:198
static std::string to_string(const char *Obj)
Definition: strconv.hxx:200
static bool is_null(const char *t)
Definition: strconv.hxx:197
static constexpr const char * name() noexcept
Definition: strconv.hxx:195
static void from_string(const char Str[], const char *&Obj)
Definition: strconv.hxx:199
static constexpr bool has_null() noexcept
Definition: strconv.hxx:196
static constexpr const char * name() noexcept
Definition: strconv.hxx:206
static bool is_null(const char *t)
Definition: strconv.hxx:208
static std::string to_string(char *Obj)
Definition: strconv.hxx:214
static constexpr bool has_null() noexcept
Definition: strconv.hxx:207
static const char * null()
Definition: strconv.hxx:209
static constexpr bool has_null() noexcept
Definition: strconv.hxx:221
static constexpr const char * name() noexcept
Definition: strconv.hxx:220
static const char * null()
Definition: strconv.hxx:223
static bool is_null(const char t[])
Definition: strconv.hxx:222
static std::string to_string(const char Obj[])
Definition: strconv.hxx:224
static bool is_null(const std::string &)
Definition: strconv.hxx:231
static void from_string(const char Str[], std::string &Obj)
Definition: strconv.hxx:234
static std::string to_string(const std::string &Obj)
Definition: strconv.hxx:235
static constexpr bool has_null() noexcept
Definition: strconv.hxx:230
static constexpr const char * name() noexcept
Definition: strconv.hxx:229
static std::string null()
Definition: strconv.hxx:232
static const std::string null()
Definition: strconv.hxx:243
static constexpr const char * name() noexcept
Definition: strconv.hxx:240
static const std::string to_string(const std::string &Obj)
Definition: strconv.hxx:245
static bool is_null(const std::string &)
Definition: strconv.hxx:242
static constexpr bool has_null() noexcept
Definition: strconv.hxx:241
static constexpr bool has_null() noexcept
Definition: strconv.hxx:251
static bool is_null(const std::stringstream &)
Definition: strconv.hxx:252
static std::string to_string(const std::stringstream &Obj)
Definition: strconv.hxx:257
static void from_string(const char Str[], std::stringstream &Obj)
Definition: strconv.hxx:255
static constexpr const char * name() noexcept
Definition: strconv.hxx:250
static std::stringstream null()
Definition: strconv.hxx:253