libpqxx 4.0
strconv.hxx
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