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-2010, 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_UTIL
00019 #define PQXX_H_UTIL
00020 
00021 #include "pqxx/compiler-public.hxx"
00022 
00023 #include <cstdio>
00024 #include <cctype>
00025 #include <stdexcept>
00026 #include <string>
00027 #include <typeinfo>
00028 #include <vector>
00029 
00030 #ifdef PQXX_TR1_HEADERS
00031 #include <tr1/memory>
00032 #else
00033 #include <memory>
00034 #endif
00035 
00036 
00259 
00260 namespace pqxx {}
00261 
00263 
00268 namespace PGSTD {}
00269 
00270 #include <pqxx/libpq-forward.hxx>
00271 
00272 
00273 namespace pqxx
00274 {
00276 
00278 struct PQXX_LIBEXPORT thread_safety_model
00279 {
00281 
00288   bool have_strerror_r;
00289 
00291 
00298   bool safe_libpq;
00299 
00301 
00304   bool safe_query_cancel;
00305 
00307 
00312   bool safe_result_copy;
00313 
00315 
00321   bool safe_kerberos;
00322 
00324   PGSTD::string description;
00325 };
00326 
00328 thread_safety_model describe_thread_safety() throw ();
00329 
00331 const oid oid_none = 0;
00332 
00334 
00356 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00357 class items : public CONT
00358 {
00359 public:
00361   items() : CONT() {}                                                   //[t80]
00363   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00364   items(const T &t1, const T &t2) : CONT()                              //[t80]
00365         { push_back(t1); push_back(t2); }
00366   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00367         { push_back(t1); push_back(t2); push_back(t3); }
00368   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00369         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00370   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00371         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00373   items(const CONT &c) : CONT(c) {}                                     //[t0]
00374 
00376   items &operator()(const T &t)                                         //[t80]
00377   {
00378     push_back(t);
00379     return *this;
00380   }
00381 };
00382 
00383 
00384 namespace internal
00385 {
00386 // TODO: Does standard library provide a ready-made version of this?
00388 template<typename ITER> struct dereference
00389 {
00390   typename ITER::value_type operator()(ITER i) const { return *i; }
00391 };
00392 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00393 } // namespace internal
00394 
00395 
00397 
00403 template<typename ITER, typename ACCESS> inline
00404 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00405     ITER begin,
00406     ITER end,
00407     ACCESS access)
00408 {
00409   PGSTD::string result;
00410   if (begin != end)
00411   {
00412     result = to_string(access(begin));
00413     for (++begin; begin != end; ++begin)
00414     {
00415       result += sep;
00416       result += to_string(access(begin));
00417     }
00418   }
00419   return result;
00420 }
00421 
00426 
00428 template<typename ITER> inline PGSTD::string
00429 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00430         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00431 
00432 
00434 template<typename OBJ> inline PGSTD::string
00435 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00436         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00437 
00438 
00440 template<typename CONTAINER> inline PGSTD::string
00441 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00442         { return separated_list(sep, c.begin(), c.end()); }
00444 
00446 
00455 namespace internal
00456 {
00457 typedef unsigned long result_size_type;
00458 typedef long result_difference_type;
00459 } // namespace internal
00460 
00461 
00462 namespace internal
00463 {
00464 void PQXX_LIBEXPORT freepqmem(const void *);
00465 template<typename P> inline void freepqmem_templated(P *p)
00466 {
00467   freepqmem(p);
00468 }
00469 
00470 
00471 #ifdef PQXX_HAVE_SHARED_PTR
00472 
00474 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
00475   class PQAlloc : protected PQXXTR1::shared_ptr<T>
00476 {
00477   typedef PQXXTR1::shared_ptr<T> super;
00478 public:
00479   typedef T content_type;
00480   PQAlloc() : super() {}
00481   explicit PQAlloc(T *t) : super(t, DELETER) {}
00482 
00483   using super::get;
00484   using super::operator=;
00485   using super::operator->;
00486   using super::operator*;
00487   using super::reset;
00488   using super::swap;
00489 };
00490 
00491 #else // !PQXX_HAVE_SHARED_PTR
00492 
00495 class PQXX_LIBEXPORT refcount
00496 {
00497   refcount *volatile m_l, *volatile m_r;
00498 
00499 public:
00500   refcount();
00501   ~refcount();
00502 
00504   void makeref(refcount &) throw ();
00505 
00507   bool loseref() throw ();
00508 
00509 private:
00511   refcount(const refcount &);
00513   refcount &operator=(const refcount &);
00514 };
00515 
00516 
00518 
00532 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
00533 class PQAlloc
00534 {
00535   T *m_Obj;
00536   mutable refcount m_rc;
00537 public:
00538   typedef T content_type;
00539 
00540   PQAlloc() throw () : m_Obj(0), m_rc() {}
00541   PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
00542   ~PQAlloc() throw () { loseref(); }
00543 
00544   PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
00545 
00547 
00549   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
00550 
00551   void swap(PQAlloc &rhs) throw ()
00552   {
00553     PQAlloc tmp(*this);
00554     *this = rhs;
00555     rhs = tmp;
00556   }
00557 
00558   //PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
00559 
00561   operator bool() const throw () { return m_Obj != 0; }
00562 
00564   bool operator!() const throw () { return !m_Obj; }
00565 
00567 
00569   T *operator->() const throw (PGSTD::logic_error)
00570   {
00571     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00572     return m_Obj;
00573   }
00574 
00576 
00578   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00579 
00581 
00583   T *get() const throw () { return m_Obj; }
00584 
00585   void reset() throw () { loseref(); }
00586 
00587 private:
00588   void makeref(T *p) throw () { m_Obj = p; }
00589 
00590   void makeref(const PQAlloc &rhs) throw ()
00591   {
00592     m_Obj = rhs.m_Obj;
00593     m_rc.makeref(rhs.m_rc);
00594   }
00595 
00597   void loseref() throw ()
00598   {
00599     if (m_rc.loseref() && m_Obj) DELETER(m_Obj);
00600     m_Obj = 0;
00601   }
00602 
00603   void redoref(const PQAlloc &rhs) throw ()
00604         { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00605   void redoref(T *obj) throw ()
00606         { if (obj != m_Obj) { loseref(); makeref(obj); } }
00607 };
00608 
00609 #endif // PQXX_HAVE_SHARED_PTR
00610 
00611 
00612 template<typename T> class scoped_array
00613 {
00614   T *m_ptr;
00615 public:
00616   typedef size_t size_type;
00617   typedef long difference_type;
00618 
00619   scoped_array() : m_ptr(0) {}
00620   explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00621   explicit scoped_array(T *t) : m_ptr(t) {}
00622   ~scoped_array() { delete [] m_ptr; }
00623 
00624   T *get() const throw () { return m_ptr; }
00625   T &operator*() const throw () { return *m_ptr; }
00626   template<typename INDEX> T &operator[](INDEX i) const throw ()
00627         { return m_ptr[i]; }
00628 
00629   scoped_array &operator=(T *t) throw ()
00630   {
00631     if (t != m_ptr)
00632     {
00633       delete [] m_ptr;
00634       m_ptr = t;
00635     }
00636     return *this;
00637   }
00638 
00639 private:
00641   scoped_array(const scoped_array &);
00642   scoped_array &operator=(const scoped_array &);
00643 };
00644 
00645 
00646 class PQXX_LIBEXPORT namedclass
00647 {
00648 public:
00649   namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
00650     m_Classname(Classname),
00651     m_Name(Name)
00652   {
00653   }
00654 
00655   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00656   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00657   PGSTD::string description() const;
00658 
00659 private:
00660   PGSTD::string m_Classname, m_Name;
00661 };
00662 
00663 
00664 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00665 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00666 
00667 
00669 
00672 template<typename GUEST>
00673 class unique
00674 {
00675 public:
00676   unique() : m_Guest(0) {}
00677 
00678   GUEST *get() const throw () { return m_Guest; }
00679 
00680   void Register(GUEST *G)
00681   {
00682     CheckUniqueRegistration(G, m_Guest);
00683     m_Guest = G;
00684   }
00685 
00686   void Unregister(GUEST *G)
00687   {
00688     CheckUniqueUnregistration(G, m_Guest);
00689     m_Guest = 0;
00690   }
00691 
00692 private:
00693   GUEST *m_Guest;
00694 
00696   unique(const unique &);
00698   unique &operator=(const unique &);
00699 };
00700 
00702 
00705 void PQXX_LIBEXPORT sleep_seconds(int);
00706 
00708 typedef const char *cstring;
00709 
00711 
00720 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00721   throw ();
00722 
00723 
00725 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00726 
00727 } // namespace internal
00728 } // namespace pqxx
00729 
00730 #endif
00731 

Generated on Mon Feb 15 18:22:41 2010 for libpqxx by  doxygen 1.5.5