util.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/util.hxx
00005  *
00006  *   DESCRIPTION
00007  *      Various utility definitions for libpqxx
00008  *      DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead.
00009  *
00010  * Copyright (c) 2001-2006, 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 #include "pqxx/compiler-public.hxx"
00019 
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 #include <vector>
00027 
00065 
00066 namespace pqxx {}
00067 
00069 
00074 namespace PGSTD {}
00075 
00076 #include <pqxx/libpq-forward.hxx>
00077 
00078 
00079 namespace pqxx
00080 {
00082 const oid oid_none = 0;
00083 
00106 
00108 
00121 template<typename T> void error_unsupported_type_in_string_conversion(T);
00122 
00123 
00125 
00131 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00132 
00133 
00134 
00135 // TODO: Implement date conversions
00136 
00138 
00150 template<typename T> void from_string(const char Str[], T &Obj);
00151 
00153 
00159 template<typename T> void from_string(const char Str[], T &Obj, size_t)
00160 {
00161   return from_string(Str, Obj);
00162 }
00163 
00164 template<> void PQXX_LIBEXPORT from_string(const char Str[],
00165         PGSTD::string &,
00166         size_t);                                                        //[t0]
00167 
00168 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00169 template<>
00170   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00171 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00172 template<>
00173   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00174 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00175 template<>
00176   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00177 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00178 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00179 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00180 
00181 #if defined(PQXX_HAVE_LONG_LONG) && defined(PQXX_ALLOW_LONG_LONG)
00182 template<> void PQXX_LIBEXPORT
00183   from_string(const char Str[], long long &);                           //[t0]
00184 template<> void PQXX_LIBEXPORT
00185   from_string(const char Str[], unsigned long long &);                  //[t0]
00186 #endif
00187 
00188 #if defined(PQXX_HAVE_LONG_DOUBLE)
00189 template<>
00190   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00191 #endif
00192 
00193 
00194 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00195         { Obj = Str; }
00196 
00197 template<>
00198   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00199         { Obj.clear(); Obj << Str; }
00200 
00201 template<typename T>
00202   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00203         { from_string(Str.c_str(), Obj); }
00204 
00205 template<typename T>
00206   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00207         { from_string(Str.str(), Obj); }
00208 
00209 template<> inline void
00210 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00211         { Obj = Str; }
00212 
00213 template<> inline void
00214 from_string(const char [], char &Obj)
00215         { error_ambiguous_string_conversion(Obj); }
00216 template<> inline void
00217 from_string(const char [], signed char &Obj)
00218         { error_ambiguous_string_conversion(Obj); }
00219 template<> inline void
00220 from_string(const char [], unsigned char &Obj)
00221         { error_ambiguous_string_conversion(Obj); }
00222 
00223 template<> inline void
00224 from_string(const PGSTD::string &, char &Obj)
00225         { error_ambiguous_string_conversion(Obj); }
00226 template<> inline void
00227 from_string(const PGSTD::string &, signed char &Obj)
00228         { error_ambiguous_string_conversion(Obj); }
00229 template<> inline void
00230 from_string(const PGSTD::string &, unsigned char &Obj)
00231         { error_ambiguous_string_conversion(Obj); }
00232 
00233 
00234 namespace internal
00235 {
00237 inline int digit_to_number(char c) throw () { return c-'0'; }
00238 inline char number_to_digit(int i) throw () { return static_cast<char>(i)+'0'; }
00239 }
00240 
00241 
00243 
00247 template<typename T> PGSTD::string to_string(const T &);
00248 
00249 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00250 template<>
00251   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00252 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00253 template<>
00254   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00255 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00256 template<>
00257   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00258 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00259 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00260 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00261 
00262 /* Even if the compiler supports "long long" and friends, the user may not want
00263  * them used because they may break compilation of client programs with
00264  * different compiler options.
00265  * When "long long" becomes a standard feature (both de jure and de facto),
00266  * we'll make long long support the default and provide a different option to
00267  * suppress these declarations.
00268  */
00269 #if defined(PQXX_HAVE_LONG_LONG) && defined(PQXX_ALLOW_LONG_LONG)
00271 template<> PGSTD::string PQXX_LIBEXPORT
00272   to_string(const long long &);                                         //[t0]
00274 template<> PGSTD::string PQXX_LIBEXPORT
00275   to_string(const unsigned long long &);                                //[t0]
00276 #endif
00277 
00278 #if defined(PQXX_HAVE_LONG_DOUBLE)
00279 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00280 #endif
00281 
00282 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00283         { return PGSTD::string(Obj); }
00284 
00285 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00286         { return Obj.str(); }
00287 
00288 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00289 
00290 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00291 
00292 
00293 template<> inline PGSTD::string to_string(const signed char &Obj)
00294         { return error_ambiguous_string_conversion(Obj); }
00295 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00296         { return error_ambiguous_string_conversion(Obj); }
00298 
00300 
00322 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00323 class items : public CONT
00324 {
00325 public:
00327   items() : CONT() {}                                                   //[t80]
00329   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00330   items(const T &t1, const T &t2) : CONT()                              //[t80]
00331         { push_back(t1); push_back(t2); }
00332   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00333         { push_back(t1); push_back(t2); push_back(t3); }
00334   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00335         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00336   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00337         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00339   items(const CONT &c) : CONT(c) {}                                     //[t0]
00340 
00342   items &operator()(const T &t)                                         //[t80]
00343   {
00344     push_back(t);
00345     return *this;
00346   }
00347 };
00348 
00349 
00350 namespace internal
00351 {
00352 // TODO: Does standard library provide a ready-made version of this?
00354 template<typename ITER> struct dereference
00355 {
00356   typename ITER::value_type operator()(ITER i) const { return *i; }
00357 };
00358 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00359 }
00360 
00361 
00363 
00369 template<typename ITER, typename ACCESS> inline
00370 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00371     ITER begin,
00372     ITER end,
00373     ACCESS access)
00374 {
00375   PGSTD::string result;
00376   if (begin != end)
00377   {
00378     result = to_string(access(begin));
00379     for (++begin; begin != end; ++begin)
00380     {
00381       result += sep;
00382       result += to_string(access(begin));
00383     }
00384   }
00385   return result;
00386 }
00387 
00392 
00394 template<typename ITER> inline PGSTD::string
00395 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00396         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00397 
00398 
00400 template<typename OBJ> inline PGSTD::string
00401 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00402         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00403 
00404 
00406 template<typename CONTAINER> inline PGSTD::string
00407 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00408         { return separated_list(sep, c.begin(), c.end()); }
00410 
00412 
00421 namespace internal
00422 {
00423 typedef unsigned long result_size_type;
00424 typedef long result_difference_type;
00425 } // namespace internal
00426 
00427 
00428 namespace internal
00429 {
00431 
00433 PGSTD::string escape_string(const char str[], size_t maxlen) PQXX_DEPRECATED;
00434 } // namespace internal
00435 
00436 
00437 
00504 
00505 
00516 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]) PQXX_DEPRECATED;
00517 
00519 
00531 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen)
00532         PQXX_DEPRECATED;
00533 
00535 
00541 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &) PQXX_DEPRECATED;
00542 
00544 
00545 
00546 namespace internal
00547 {
00548 void PQXX_LIBEXPORT freepqmem(void *);
00549 
00550 
00552 class PQXX_LIBEXPORT refcount
00553 {
00554   refcount *volatile m_l, *volatile m_r;
00555 
00556 public:
00557   refcount();
00558   ~refcount();
00559 
00561   void makeref(refcount &) throw ();
00562 
00564   bool loseref() throw ();
00565 
00566 private:
00568   refcount(const refcount &);
00570   refcount &operator=(const refcount &);
00571 };
00572 
00573 
00575 
00589 template<typename T> class PQAlloc
00590 {
00591   T *m_Obj;
00592   mutable refcount m_rc;
00593 public:
00594   typedef T content_type;
00595 
00596   PQAlloc() throw () : m_Obj(0), m_rc() {}
00597   PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
00598   ~PQAlloc() throw () { loseref(); }
00599 
00600   PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
00601 
00603 
00605   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
00606 
00607   void swap(PQAlloc &rhs) throw ()
00608   {
00609     PQAlloc tmp(*this);
00610     *this = rhs;
00611     rhs = tmp;
00612   }
00613 
00614   PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
00615 
00617   operator bool() const throw () { return m_Obj != 0; }
00618 
00620   bool operator!() const throw () { return !m_Obj; }
00621 
00623 
00625   T *operator->() const throw (PGSTD::logic_error)
00626   {
00627     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00628     return m_Obj;
00629   }
00630 
00632 
00634   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00635 
00637 
00639   T *c_ptr() const throw () { return m_Obj; }
00640 
00641   void clear() throw () { loseref(); }
00642 
00643 private:
00644   void makeref(T *p) throw () { m_Obj = p; }
00645 
00646   void makeref(const PQAlloc &rhs) throw ()
00647   {
00648     m_Obj = rhs.m_Obj;
00649     m_rc.makeref(rhs.m_rc);
00650   }
00651 
00653   void loseref() throw ()
00654   {
00655     if (m_rc.loseref() && m_Obj) freemem();
00656     m_Obj = 0;
00657   }
00658 
00659   void redoref(const PQAlloc &rhs) throw ()
00660         { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00661   void redoref(T *obj) throw ()
00662         { if (obj != m_Obj) { loseref(); makeref(obj); } }
00663 
00664   void freemem() throw () { freepqmem(m_Obj); }
00665 };
00666 
00667 
00668 void PQXX_LIBEXPORT freemem_notif(pq::PGnotify *) throw ();
00669 template<> inline void PQAlloc<pq::PGnotify>::freemem() throw ()
00670         { freemem_notif(m_Obj); }
00671 
00672 
00673 
00674 template<typename T> class scoped_array
00675 {
00676   T *m_ptr;
00677 public:
00678   typedef size_t size_type;
00679   typedef long difference_type;
00680 
00681   scoped_array() : m_ptr(0) {}
00682   explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00683   explicit scoped_array(T *t) : m_ptr(t) {}
00684   ~scoped_array() { delete [] m_ptr; }
00685 
00686   T *c_ptr() const throw () { return m_ptr; }
00687   T &operator*() const throw () { return *m_ptr; }
00688   T &operator[](difference_type i) const throw () { return m_ptr[i]; }
00689 
00690   scoped_array &operator=(T *t) throw ()
00691   {
00692     if (t != m_ptr)
00693     {
00694       delete [] m_ptr;
00695       m_ptr = t;
00696     }
00697     return *this;
00698   }
00699 
00700 private:
00702   scoped_array(const scoped_array &);
00703   scoped_array &operator=(const scoped_array &);
00704 };
00705 
00706 
00707 class PQXX_LIBEXPORT namedclass
00708 {
00709 public:
00710   namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
00711     m_Classname(Classname),
00712     m_Name(Name)
00713   {
00714   }
00715 
00716   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00717   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00718   PGSTD::string description() const;
00719 
00720 private:
00721   PGSTD::string m_Classname, m_Name;
00722 };
00723 
00724 
00725 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00726 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00727 
00728 
00730 
00733 template<typename GUEST>
00734 class unique
00735 {
00736 public:
00737   unique() : m_Guest(0) {}
00738 
00739   GUEST *get() const throw () { return m_Guest; }
00740 
00741   void Register(GUEST *G)
00742   {
00743     CheckUniqueRegistration(G, m_Guest);
00744     m_Guest = G;
00745   }
00746 
00747   void Unregister(GUEST *G)
00748   {
00749     CheckUniqueUnregistration(G, m_Guest);
00750     m_Guest = 0;
00751   }
00752 
00753 private:
00754   GUEST *m_Guest;
00755 
00757   unique(const unique &);
00759   unique &operator=(const unique &);
00760 };
00761 
00763 
00766 void PQXX_LIBEXPORT sleep_seconds(int);
00767 
00769 typedef const char *cstring;
00770 
00772 
00781 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00782   throw ();
00783 
00784 
00786 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00787 
00788 } // namespace internal
00789 } // namespace pqxx
00790 

Generated on Thu Feb 1 17:12:08 2007 for libpqxx by  doxygen 1.5.1