libpqxx 4.0
|
00001 /*------------------------------------------------------------------------- 00002 * 00003 * FILE 00004 * pqxx/stringconv.hxx 00005 * 00006 * DESCRIPTION 00007 * String conversion definitions for libpqxx 00008 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. 00009 * 00010 * Copyright (c) 2008-2011, Jeroen T. Vermeulen <jtv@xs4all.nl> 00011 * 00012 * See COPYING for copyright license. If you did not receive a file called 00013 * COPYING with this source code, please notify the distributor of this mistake, 00014 * or contact the author. 00015 * 00016 *------------------------------------------------------------------------- 00017 */ 00018 #ifndef PQXX_H_STRINGCONV 00019 #define PQXX_H_STRINGCONV 00020 00021 #include "pqxx/compiler-public.hxx" 00022 00023 #include <sstream> 00024 #include <stdexcept> 00025 00026 00027 namespace pqxx 00028 { 00029 00041 00043 00046 template<typename T> struct string_traits {}; 00047 00048 namespace internal 00049 { 00051 void PQXX_LIBEXPORT PQXX_NORETURN throw_null_conversion( 00052 const PGSTD::string &type); 00053 } // namespace pqxx::internal 00054 00055 #define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T) \ 00056 template<> struct PQXX_LIBEXPORT string_traits<T> \ 00057 { \ 00058 typedef T subject_type; \ 00059 static const char *name() { return #T; } \ 00060 static bool has_null() { return false; } \ 00061 static bool is_null(T) { return false; } \ 00062 static T null() \ 00063 { internal::throw_null_conversion(name()); return subject_type(); } \ 00064 static void from_string(const char Str[], T &Obj); \ 00065 static PGSTD::string to_string(T Obj); \ 00066 }; 00067 00068 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool) 00069 00070 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short) 00071 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short) 00072 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int) 00073 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int) 00074 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long) 00075 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long) 00076 #ifdef PQXX_HAVE_LONG_LONG 00077 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long) 00078 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long) 00079 #endif 00080 00081 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float) 00082 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double) 00083 #ifdef PQXX_HAVE_LONG_DOUBLE 00084 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double) 00085 #endif 00086 00087 #undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION 00088 00090 template<> struct PQXX_LIBEXPORT string_traits<const char *> 00091 { 00092 static const char *name() { return "const char *"; } 00093 static bool has_null() { return true; } 00094 static bool is_null(const char *t) { return !t; } 00095 static const char *null() { return NULL; } 00096 static void from_string(const char Str[], const char *&Obj) { Obj = Str; } 00097 static PGSTD::string to_string(const char *Obj) { return Obj; } 00098 }; 00099 00101 template<> struct PQXX_LIBEXPORT string_traits<char *> 00102 { 00103 static const char *name() { return "char *"; } 00104 static bool has_null() { return true; } 00105 static bool is_null(const char *t) { return !t; } 00106 static const char *null() { return NULL; } 00107 00108 // Don't allow this conversion since it breaks const-safety. 00109 // static void from_string(const char Str[], char *&Obj); 00110 00111 static PGSTD::string to_string(char *Obj) { return Obj; } 00112 }; 00113 00115 template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]> 00116 { 00117 static const char *name() { return "char[]"; } 00118 static bool has_null() { return true; } 00119 static bool is_null(const char t[]) { return !t; } 00120 static const char *null() { return NULL; } 00121 static PGSTD::string to_string(const char Obj[]) { return Obj; } 00122 }; 00123 00125 00128 template<size_t N> struct PQXX_LIBEXPORT string_traits<const char[N]> 00129 { 00130 static const char *name() { return "char[]"; } 00131 static bool has_null() { return true; } 00132 static bool is_null(const char t[]) { return !t; } 00133 static const char *null() { return NULL; } 00134 static PGSTD::string to_string(const char Obj[]) { return Obj; } 00135 }; 00136 00137 00138 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::string> 00139 { 00140 static const char *name() { return "string"; } 00141 static bool has_null() { return false; } 00142 static bool is_null(const PGSTD::string &) { return false; } 00143 static PGSTD::string null() 00144 { internal::throw_null_conversion(name()); return PGSTD::string(); } 00145 static void from_string(const char Str[], PGSTD::string &Obj) { Obj=Str; } 00146 static PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; } 00147 }; 00148 00149 template<> struct PQXX_LIBEXPORT string_traits<const PGSTD::string> 00150 { 00151 static const char *name() { return "const string"; } 00152 static bool has_null() { return false; } 00153 static bool is_null(const PGSTD::string &) { return false; } 00154 static const PGSTD::string null() 00155 { internal::throw_null_conversion(name()); return PGSTD::string(); } 00156 static const PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; } 00157 }; 00158 00159 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::stringstream> 00160 { 00161 static const char *name() { return "stringstream"; } 00162 static bool has_null() { return false; } 00163 static bool is_null(const PGSTD::stringstream &) { return false; } 00164 static PGSTD::stringstream null() 00165 { 00166 internal::throw_null_conversion(name()); 00167 // No, dear compiler, we don't need a return here. 00168 throw 0; 00169 } 00170 static void from_string(const char Str[], PGSTD::stringstream &Obj) 00171 { Obj.clear(); Obj << Str; } 00172 static PGSTD::string to_string(const PGSTD::stringstream &Obj) 00173 { return Obj.str(); } 00174 }; 00175 00176 00177 // TODO: Implement date conversions 00178 00180 00192 template<typename T> 00193 inline void from_string(const char Str[], T &Obj) 00194 { 00195 if (!Str) 00196 throw PGSTD::runtime_error("Attempt to read NULL string"); 00197 string_traits<T>::from_string(Str, Obj); 00198 } 00199 00200 00202 00208 template<typename T> inline void from_string(const char Str[], T &Obj, size_t) 00209 { 00210 return from_string(Str, Obj); 00211 } 00212 00213 template<> 00214 inline void from_string<PGSTD::string>(const char Str[], 00215 PGSTD::string &Obj, 00216 size_t len) //[t0] 00217 { 00218 if (!Str) 00219 throw PGSTD::runtime_error("Attempt to read NULL string"); 00220 Obj.assign(Str, len); 00221 } 00222 00223 template<typename T> 00224 inline void from_string(const PGSTD::string &Str, T &Obj) //[t45] 00225 { from_string(Str.c_str(), Obj); } 00226 00227 template<typename T> 00228 inline void from_string(const PGSTD::stringstream &Str, T &Obj) //[t0] 00229 { from_string(Str.str(), Obj); } 00230 00231 template<> inline void 00232 from_string(const PGSTD::string &Str, PGSTD::string &Obj) //[t46] 00233 { Obj = Str; } 00234 00235 00236 namespace internal 00237 { 00239 inline int digit_to_number(char c) throw () { return c-'0'; } 00240 inline char number_to_digit(int i) throw () { return static_cast<char>(i+'0'); } 00241 } // namespace pqxx::internal 00242 00243 00245 00249 template<typename T> inline PGSTD::string to_string(const T &Obj) 00250 { return string_traits<T>::to_string(Obj); } 00251 00253 00254 } // namespace pqxx 00255 00256 #endif 00257