libpqxx  4.0.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-2011, 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 PQXX_NORETURN throw_null_conversion(
52  const PGSTD::string &type);
53 } // namespace pqxx::internal
54 
55 #define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T) \
56 template<> struct PQXX_LIBEXPORT string_traits<T> \
57 { \
58  typedef T subject_type; \
59  static const char *name() { return #T; } \
60  static bool has_null() { return false; } \
61  static bool is_null(T) { return false; } \
62  static T null() \
63  { internal::throw_null_conversion(name()); return subject_type(); } \
64  static void from_string(const char Str[], T &Obj); \
65  static PGSTD::string to_string(T Obj); \
66 };
67 
69 
76 #ifdef PQXX_HAVE_LONG_LONG
79 #endif
80 
83 #ifdef PQXX_HAVE_LONG_DOUBLE
85 #endif
86 
87 #undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
88 
90 template<> struct PQXX_LIBEXPORT string_traits<const char *>
91 {
92  static const char *name() { return "const char *"; }
93  static bool has_null() { return true; }
94  static bool is_null(const char *t) { return !t; }
95  static const char *null() { return NULL; }
96  static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
97  static PGSTD::string to_string(const char *Obj) { return Obj; }
98 };
99 
101 template<> struct PQXX_LIBEXPORT string_traits<char *>
102 {
103  static const char *name() { return "char *"; }
104  static bool has_null() { return true; }
105  static bool is_null(const char *t) { return !t; }
106  static const char *null() { return NULL; }
107 
108  // Don't allow this conversion since it breaks const-safety.
109  // static void from_string(const char Str[], char *&Obj);
110 
111  static PGSTD::string to_string(char *Obj) { return Obj; }
112 };
113 
115 template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
116 {
117  static const char *name() { return "char[]"; }
118  static bool has_null() { return true; }
119  static bool is_null(const char t[]) { return !t; }
120  static const char *null() { return NULL; }
121  static PGSTD::string to_string(const char Obj[]) { return Obj; }
122 };
123 
125 
128 template<size_t N> struct PQXX_LIBEXPORT string_traits<const char[N]>
129 {
130  static const char *name() { return "char[]"; }
131  static bool has_null() { return true; }
132  static bool is_null(const char t[]) { return !t; }
133  static const char *null() { return NULL; }
134  static PGSTD::string to_string(const char Obj[]) { return Obj; }
135 };
136 
137 
138 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::string>
139 {
140  static const char *name() { return "string"; }
141  static bool has_null() { return false; }
142  static bool is_null(const PGSTD::string &) { return false; }
143  static PGSTD::string null()
144  { internal::throw_null_conversion(name()); return PGSTD::string(); }
145  static void from_string(const char Str[], PGSTD::string &Obj) { Obj=Str; }
146  static PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; }
147 };
148 
149 template<> struct PQXX_LIBEXPORT string_traits<const PGSTD::string>
150 {
151  static const char *name() { return "const string"; }
152  static bool has_null() { return false; }
153  static bool is_null(const PGSTD::string &) { return false; }
154  static const PGSTD::string null()
155  { internal::throw_null_conversion(name()); return PGSTD::string(); }
156  static const PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; }
157 };
158 
159 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::stringstream>
160 {
161  static const char *name() { return "stringstream"; }
162  static bool has_null() { return false; }
163  static bool is_null(const PGSTD::stringstream &) { return false; }
164  static PGSTD::stringstream null()
165  {
167  // No, dear compiler, we don't need a return here.
168  throw 0;
169  }
170  static void from_string(const char Str[], PGSTD::stringstream &Obj)
171  { Obj.clear(); Obj << Str; }
172  static PGSTD::string to_string(const PGSTD::stringstream &Obj)
173  { return Obj.str(); }
174 };
175 
176 
177 // TODO: Implement date conversions
178 
180 
192 template<typename T>
193  inline void from_string(const char Str[], T &Obj)
194 {
195  if (!Str)
196  throw PGSTD::runtime_error("Attempt to read NULL string");
198 }
199 
200 
202 
208 template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
209 {
210  return from_string(Str, Obj);
211 }
212 
213 template<>
214  inline void from_string<PGSTD::string>(const char Str[],
215  PGSTD::string &Obj,
216  size_t len) //[t0]
217 {
218  if (!Str)
219  throw PGSTD::runtime_error("Attempt to read NULL string");
220  Obj.assign(Str, len);
221 }
222 
223 template<typename T>
224  inline void from_string(const PGSTD::string &Str, T &Obj) //[t45]
225  { from_string(Str.c_str(), Obj); }
226 
227 template<typename T>
228  inline void from_string(const PGSTD::stringstream &Str, T &Obj) //[t0]
229  { from_string(Str.str(), Obj); }
230 
231 template<> inline void
232 from_string(const PGSTD::string &Str, PGSTD::string &Obj) //[t46]
233  { Obj = Str; }
234 
235 
236 namespace internal
237 {
239 inline int digit_to_number(char c) throw () { return c-'0'; }
240 inline char number_to_digit(int i) throw () { return static_cast<char>(i+'0'); }
241 } // namespace pqxx::internal
242 
243 
245 
249 template<typename T> inline PGSTD::string to_string(const T &Obj)
250  { return string_traits<T>::to_string(Obj); }
251 
253 
254 } // namespace pqxx
255 
256 #endif
257