util.hxx

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-2016, 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 <memory>
00026 #include <stdexcept>
00027 #include <string>
00028 #include <typeinfo>
00029 #include <vector>
00030 
00031 #include "pqxx/strconv"
00032 
00033 
00256 
00257 namespace pqxx {}
00258 
00259 #include <pqxx/internal/libpq-forward.hxx>
00260 
00261 
00262 namespace pqxx
00263 {
00265 
00267 struct PQXX_LIBEXPORT thread_safety_model
00268 {
00270 
00277   bool have_safe_strerror;
00278 
00280 
00287   bool safe_libpq;
00288 
00290 
00293   bool safe_query_cancel;
00294 
00296 
00301   bool safe_result_copy;
00302 
00304 
00310   bool safe_kerberos;
00311 
00313   std::string description;
00314 };
00315 
00317 PQXX_LIBEXPORT thread_safety_model describe_thread_safety() PQXX_NOEXCEPT;
00318 
00320 const oid oid_none = 0;
00321 
00323 
00345 template<typename T=std::string, typename CONT=std::vector<T> >
00346 class items : public CONT
00347 {
00348 public:
00350   items() : CONT() {}                                                   //[t0]
00352   explicit items(const T &t) : CONT() { this->push_back(t); }           //[t0]
00353   items(const T &t1, const T &t2) : CONT()                              //[t0]
00354         { this->push_back(t1); this->push_back(t2); }
00355   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00356         { this->push_back(t1); this->push_back(t2); this->push_back(t3); }
00357   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00358   {
00359     this->push_back(t1);
00360     this->push_back(t2);
00361     this->push_back(t3);
00362     this->push_back(t4);
00363   }
00364   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00365   {
00366     this->push_back(t1);
00367     this->push_back(t2);
00368     this->push_back(t3);
00369     this->push_back(t4);
00370     this->push_back(t5);
00371   }
00373   items(const CONT &c) : CONT(c) {}                                     //[t0]
00374 
00376   items &operator()(const T &t)                                         //[t0]
00377   {
00378     this->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 std::string separated_list(const std::string &sep,                      //[t0]
00405     ITER begin,
00406     ITER end,
00407     ACCESS access)
00408 {
00409   std::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 std::string
00429 separated_list(const std::string &sep, ITER begin, ITER end)            //[t0]
00430         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00431 
00432 
00434 template<typename OBJ> inline std::string
00435 separated_list(const std::string &sep, OBJ *begin, OBJ *end)            //[t0]
00436         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00437 
00438 
00440 template<typename CONTAINER> inline std::string
00441 separated_list(const std::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 PQXX_LIBEXPORT void freepqmem(const void *) PQXX_NOEXCEPT;
00465 template<typename P> inline void freepqmem_templated(P *p) PQXX_NOEXCEPT
00466 {
00467   freepqmem(p);
00468 }
00469 
00470 PQXX_LIBEXPORT void freemallocmem(const void *) PQXX_NOEXCEPT;
00471 template<typename P> inline void freemallocmem_templated(P *p) PQXX_NOEXCEPT
00472 {
00473   freemallocmem(p);
00474 }
00475 
00476 
00477 #ifdef PQXX_HAVE_SHARED_PTR
00478 
00480 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
00481   class PQAlloc
00482 {
00483 public:
00484   typedef T content_type;
00485   PQAlloc() PQXX_NOEXCEPT : m_ptr() {}
00486   PQAlloc(const PQAlloc &rhs) PQXX_NOEXCEPT : m_ptr(rhs.m_ptr) {}
00487   explicit PQAlloc(T *t) : m_ptr(t, DELETER) {}
00488 
00489   T *get() const PQXX_NOEXCEPT { return m_ptr.get(); }
00490   PQAlloc &operator=(const PQAlloc &rhs) PQXX_NOEXCEPT
00491   {
00492     m_ptr = rhs.m_ptr;
00493     return *this;
00494   }
00495 
00496 #if __cplusplus >= 201103L
00497   PQAlloc(PQAlloc &&) =default;
00498   PQAlloc &operator=(PQAlloc &&) =default;
00499 #endif
00500 
00501   T *operator->() const PQXX_NOEXCEPT { return m_ptr.get(); }
00502   T &operator*() const PQXX_NOEXCEPT { return *m_ptr; }
00503   void reset() PQXX_NOEXCEPT { m_ptr.reset(); }
00504   void swap(PQAlloc &other) PQXX_NOEXCEPT { m_ptr.swap(other.m_ptr); }
00505 
00506 private:
00507   std::shared_ptr<T> m_ptr;
00508 };
00509 
00510 #else // !PQXX_HAVE_SHARED_PTR
00511 
00514 class PQXX_LIBEXPORT refcount
00515 {
00516   refcount *volatile m_l, *volatile m_r;
00517 
00518 public:
00519   refcount();
00520   ~refcount();
00521 
00523   void makeref(refcount &) PQXX_NOEXCEPT;
00524 
00526   bool loseref() PQXX_NOEXCEPT;
00527 
00528 private:
00530   refcount(const refcount &);
00532   refcount &operator=(const refcount &);
00533 };
00534 
00535 
00537 
00550 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
00551 class PQAlloc
00552 {
00553   T *m_Obj;
00554   mutable refcount m_rc;
00555 public:
00556   typedef T content_type;
00557 
00558   PQAlloc() PQXX_NOEXCEPT : m_Obj(0), m_rc() {}
00559   PQAlloc(const PQAlloc &rhs) PQXX_NOEXCEPT : m_Obj(0), m_rc() { makeref(rhs); }
00560   ~PQAlloc() PQXX_NOEXCEPT { loseref(); }
00561 
00562   PQAlloc &operator=(const PQAlloc &rhs) PQXX_NOEXCEPT
00563         {redoref(rhs); return *this;}
00564 
00566 
00568   explicit PQAlloc(T *obj) PQXX_NOEXCEPT : m_Obj(obj), m_rc() {}
00569 
00570   void swap(PQAlloc &rhs) PQXX_NOEXCEPT
00571   {
00572     PQAlloc tmp(*this);
00573     *this = rhs;
00574     rhs = tmp;
00575   }
00576 
00578   operator bool() const PQXX_NOEXCEPT { return m_Obj != 0; }
00579 
00581   bool operator!() const PQXX_NOEXCEPT { return !m_Obj; }
00582 
00584 
00586   T *operator->() const
00587   {
00588     if (!m_Obj) throw std::logic_error("Null pointer dereferenced");
00589     return m_Obj;
00590   }
00591 
00593 
00595   T &operator*() const { return *operator->(); }
00596 
00598 
00600   T *get() const PQXX_NOEXCEPT { return m_Obj; }
00601 
00602   void reset() PQXX_NOEXCEPT { loseref(); }
00603 
00604 private:
00605   void makeref(T *p) PQXX_NOEXCEPT { m_Obj = p; }
00606 
00607   void makeref(const PQAlloc &rhs) PQXX_NOEXCEPT
00608   {
00609     m_Obj = rhs.m_Obj;
00610     m_rc.makeref(rhs.m_rc);
00611   }
00612 
00614   void loseref() PQXX_NOEXCEPT
00615   {
00616     if (m_rc.loseref() && m_Obj) DELETER(m_Obj);
00617     m_Obj = 0;
00618   }
00619 
00620   void redoref(const PQAlloc &rhs) PQXX_NOEXCEPT
00621         { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00622   void redoref(T *obj) PQXX_NOEXCEPT
00623         { if (obj != m_Obj) { loseref(); makeref(obj); } }
00624 };
00625 
00626 #endif // PQXX_HAVE_SHARED_PTR
00627 
00628 
00629 class PQXX_LIBEXPORT namedclass
00630 {
00631 public:
00632   namedclass(const std::string &Classname, const std::string &Name="") :
00633     m_Classname(Classname),
00634     m_Name(Name)
00635   {
00636   }
00637 
00638   const std::string &name() const PQXX_NOEXCEPT { return m_Name; }      //[t1]
00639   const std::string &classname() const PQXX_NOEXCEPT                    //[t73]
00640         {return m_Classname;}
00641   std::string description() const;
00642 
00643 private:
00644   std::string m_Classname, m_Name;
00645 };
00646 
00647 
00648 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00649 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00650 
00651 
00653 
00656 template<typename GUEST>
00657 class unique
00658 {
00659 public:
00660   unique() : m_Guest(0) {}
00661 
00662   GUEST *get() const PQXX_NOEXCEPT { return m_Guest; }
00663 
00664   void Register(GUEST *G)
00665   {
00666     CheckUniqueRegistration(G, m_Guest);
00667     m_Guest = G;
00668   }
00669 
00670   void Unregister(GUEST *G)
00671   {
00672     CheckUniqueUnregistration(G, m_Guest);
00673     m_Guest = 0;
00674   }
00675 
00676 private:
00677   GUEST *m_Guest;
00678 
00680   unique(const unique &);
00682   unique &operator=(const unique &);
00683 };
00684 
00686 
00689 PQXX_LIBEXPORT void sleep_seconds(int);
00690 
00692 typedef const char *cstring;
00693 
00695 
00704 PQXX_LIBEXPORT cstring strerror_wrapper(int err, char buf[], std::size_t len)
00705   PQXX_NOEXCEPT;
00706 
00707 
00709 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00710 
00711 
00713 template<typename T> inline std::ptrdiff_t distance(T first, T last)
00714 {
00715 #ifdef PQXX_HAVE_DISTANCE
00716   return std::distance(first, last);
00717 #else
00718   // Naive implementation.  All we really need for now.
00719   std::ptrdiff_t d;
00720   for (d=0; first != last; ++d) ++first;
00721   return d;
00722 #endif
00723 }
00724 
00725 } // namespace internal
00726 } // namespace pqxx
00727 
00728 #endif
00729 

Generated on 16 Mar 2017 for libpqxx by  doxygen 1.6.1