libpqxx  3.1.1
strconv.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/stringconv.hxx
5  *
6  * DESCRIPTION
7  * String conversion definitions for libpqxx
8  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
9  *
10  * Copyright (c) 2008-2009, Jeroen T. Vermeulen <jtv@xs4all.nl>
11  *
12  * See COPYING for copyright license. If you did not receive a file called
13  * COPYING with this source code, please notify the distributor of this mistake,
14  * or contact the author.
15  *
16  *-------------------------------------------------------------------------
17  */
18 #ifndef PQXX_H_STRINGCONV
19 #define PQXX_H_STRINGCONV
20 
21 #include "pqxx/compiler-public.hxx"
22 
23 #include <sstream>
24 #include <stdexcept>
25 
26 
27 namespace pqxx
28 {
29 
41 
43 
46 template<typename T> struct string_traits {};
47 
48 namespace internal
49 {
51 void PQXX_LIBEXPORT throw_null_conversion(const PGSTD::string &type);
52 } // namespace pqxx::internal
53 
54 #define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T) \
55 template<> struct PQXX_LIBEXPORT string_traits<T> \
56 { \
57  typedef T subject_type; \
58  static const char *name() { return #T; } \
59  static bool has_null() { return false; } \
60  static bool is_null(T) { return false; } \
61  static T null() \
62  { internal::throw_null_conversion(name()); return subject_type(); } \
63  static void from_string(const char Str[], T &Obj); \
64  static PGSTD::string to_string(T Obj); \
65 };
66 
68 
75 #ifdef PQXX_HAVE_LONG_LONG
78 #endif
79 
82 #ifdef PQXX_HAVE_LONG_DOUBLE
84 #endif
85 
86 #undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
87 
89 template<> struct PQXX_LIBEXPORT string_traits<const char *>
90 {
91  static const char *name() { return "const char *"; }
92  static bool has_null() { return true; }
93  static bool is_null(const char *t) { return !t; }
94  static const char *null() { return NULL; }
95  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
96  static PGSTD::string to_string(const char *Obj) { return Obj; }
97 };
98 
100 template<> struct PQXX_LIBEXPORT string_traits<char *>
101 {
102  static const char *name() { return "char *"; }
103  static bool has_null() { return true; }
104  static bool is_null(const char *t) { return !t; }
105  static const char *null() { return NULL; }
106 
107  // Don't allow this conversion since it breaks const-safety.
108  // static void from_string(const char Str[], char *&Obj);
109 
110  static PGSTD::string to_string(char *Obj) { return Obj; }
111 };
112 
114 template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
115 {
116  static const char *name() { return "char[]"; }
117  static bool has_null() { return true; }
118  static bool is_null(const char t[]) { return !t; }
119  static const char *null() { return NULL; }
120  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
121  static PGSTD::string to_string(const char Obj[]) { return Obj; }
122 };
123 
124 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::string>
125 {
126  static const char *name() { return "string"; }
127  static bool has_null() { return false; }
128  static bool is_null(const PGSTD::string &) { return false; }
129  static PGSTD::string null()
130  { internal::throw_null_conversion(name()); return PGSTD::string(); }
131  static void from_string(const char Str[], PGSTD::string &Obj) { Obj=Str; }
132  static PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; }
133 };
134 
135 template<> struct PQXX_LIBEXPORT string_traits<const PGSTD::string>
136 {
137  static const char *name() { return "const string"; }
138  static bool has_null() { return false; }
139  static bool is_null(const PGSTD::string &) { return false; }
140  static const PGSTD::string null()
141  { internal::throw_null_conversion(name()); return PGSTD::string(); }
142  static const PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; }
143 };
144 
145 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::stringstream>
146 {
147  static const char *name() { return "stringstream"; }
148  static bool has_null() { return false; }
149  static bool is_null(const PGSTD::stringstream &) { return false; }
150  static PGSTD::stringstream null()
151  {
153  // No, dear compiler, we don't need a return here.
154  throw 0;
155  }
156  static void from_string(const char Str[], PGSTD::stringstream &Obj)
157  { Obj.clear(); Obj << Str; }
158  static PGSTD::string to_string(const PGSTD::stringstream &Obj)
159  { return Obj.str(); }
160 };
161 
162 
163 // TODO: Implement date conversions
164 
166 
178 template<typename T>
179  inline void from_string(const char Str[], T &Obj)
180 {
181  if (!Str)
182  throw PGSTD::runtime_error("Attempt to read NULL string");
184 }
185 
186 
188 
194 template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
195 {
196  return from_string(Str, Obj);
197 }
198 
199 template<>
200  inline void from_string<PGSTD::string>(const char Str[],
201  PGSTD::string &Obj,
202  size_t len) //[t0]
203 {
204  if (!Str)
205  throw PGSTD::runtime_error("Attempt to read NULL string");
206  Obj.assign(Str, len);
207 }
208 
209 template<typename T>
210  inline void from_string(const PGSTD::string &Str, T &Obj) //[t45]
211  { from_string(Str.c_str(), Obj); }
212 
213 template<typename T>
214  inline void from_string(const PGSTD::stringstream &Str, T &Obj) //[t0]
215  { from_string(Str.str(), Obj); }
216 
217 template<> inline void
218 from_string(const PGSTD::string &Str, PGSTD::string &Obj) //[t46]
219  { Obj = Str; }
220 
221 
222 namespace internal
223 {
225 inline int digit_to_number(char c) throw () { return c-'0'; }
226 inline char number_to_digit(int i) throw () { return static_cast<char>(i+'0'); }
227 } // namespace pqxx::internal
228 
229 
231 
235 template<typename T> inline PGSTD::string to_string(const T &Obj)
236  { return string_traits<T>::to_string(Obj); }
237 
238 
239 inline PGSTD::string to_string(const char Obj[]) //[t14]
240  { return Obj; }
241 
243 
244 } // namespace pqxx
245 
246 #endif
247