libpqxx  3.1.1
util.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/util.hxx
5  *
6  * DESCRIPTION
7  * Various utility definitions for libpqxx
8  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead.
9  *
10  * Copyright (c) 2001-2013, Jeroen T. Vermeulen <jtv@xs4all.nl>
11  *
12  * See COPYING for copyright license. If you did not receive a file called
13  * COPYING with this source code, please notify the distributor of this mistake,
14  * or contact the author.
15  *
16  *-------------------------------------------------------------------------
17  */
18 #ifndef PQXX_H_UTIL
19 #define PQXX_H_UTIL
20 
21 #include "pqxx/compiler-public.hxx"
22 
23 #include <cstdio>
24 #include <cctype>
25 #include <stdexcept>
26 #include <string>
27 #include <typeinfo>
28 #include <vector>
29 
30 #ifdef PQXX_TR1_HEADERS
31 #include <tr1/memory>
32 #else
33 #include <memory>
34 #endif
35 
36 #include "pqxx/strconv"
37 
38 
261 
262 namespace pqxx {}
263 
265 
270 namespace PGSTD {}
271 
272 #include <pqxx/libpq-forward.hxx>
273 
274 
275 namespace pqxx
276 {
278 
280 struct PQXX_LIBEXPORT thread_safety_model
281 {
283 
291 
293 
301 
303 
307 
309 
315 
317 
324 
326  PGSTD::string description;
327 };
328 
331 
333 const oid oid_none = 0;
334 
336 
358 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
359 class items : public CONT
360 {
361 public:
363  items() : CONT() {} //[t80]
365  explicit items(const T &t) : CONT() { this->push_back(t); } //[t0]
366  items(const T &t1, const T &t2) : CONT() //[t80]
367  { this->push_back(t1); this->push_back(t2); }
368  items(const T &t1, const T &t2, const T &t3) : CONT() //[t0]
369  { this->push_back(t1); this->push_back(t2); this->push_back(t3); }
370  items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[t0]
371  {
372  this->push_back(t1);
373  this->push_back(t2);
374  this->push_back(t3);
375  this->push_back(t4);
376  }
377  items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[t0]
378  {
379  this->push_back(t1);
380  this->push_back(t2);
381  this->push_back(t3);
382  this->push_back(t4);
383  this->push_back(t5);
384  }
386  items(const CONT &c) : CONT(c) {} //[t0]
387 
389  items &operator()(const T &t) //[t80]
390  {
391  this->push_back(t);
392  return *this;
393  }
394 };
395 
396 
397 namespace internal
398 {
399 // TODO: Does standard library provide a ready-made version of this?
401 template<typename ITER> struct dereference
402 {
403  typename ITER::value_type operator()(ITER i) const { return *i; }
404 };
405 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
406 } // namespace internal
407 
408 
410 
416 template<typename ITER, typename ACCESS> inline
417 PGSTD::string separated_list(const PGSTD::string &sep, //[t0]
418  ITER begin,
419  ITER end,
420  ACCESS access)
421 {
422  PGSTD::string result;
423  if (begin != end)
424  {
425  result = to_string(access(begin));
426  for (++begin; begin != end; ++begin)
427  {
428  result += sep;
429  result += to_string(access(begin));
430  }
431  }
432  return result;
433 }
434 
439 
441 template<typename ITER> inline PGSTD::string
442 separated_list(const PGSTD::string &sep, ITER begin, ITER end) //[t8]
443  { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
444 
445 
447 template<typename OBJ> inline PGSTD::string
448 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end) //[t9]
449  { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
450 
451 
453 template<typename CONTAINER> inline PGSTD::string
454 separated_list(const PGSTD::string &sep, const CONTAINER &c) //[t10]
455  { return separated_list(sep, c.begin(), c.end()); }
457 
459 
468 namespace internal
469 {
470 typedef unsigned long result_size_type;
472 } // namespace internal
473 
474 
475 namespace internal
476 {
477 void PQXX_LIBEXPORT freepqmem(const void *);
478 template<typename P> inline void freepqmem_templated(P *p)
479 {
480  freepqmem(p);
481 }
482 
483 
484 #ifdef PQXX_HAVE_SHARED_PTR
485 
487 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
488  class PQAlloc : protected PQXXTR1::shared_ptr<T>
489 {
490  typedef PQXXTR1::shared_ptr<T> super;
491 public:
492  typedef T content_type;
493  PQAlloc() : super() {}
494  explicit PQAlloc(T *t) : super(t, DELETER) {}
495 
496  using super::get;
497  using super::operator=;
498  using super::operator->;
499  using super::operator*;
500  using super::reset;
501  using super::swap;
502 };
503 
504 #else // !PQXX_HAVE_SHARED_PTR
505 
508 class PQXX_LIBEXPORT refcount
509 {
510  refcount *volatile m_l, *volatile m_r;
511 
512 public:
513  refcount();
514  ~refcount();
515 
517  void makeref(refcount &) throw ();
518 
520  bool loseref() throw ();
521 
522 private:
524  refcount(const refcount &);
526  refcount &operator=(const refcount &);
527 };
528 
529 
531 
545 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
546 class PQAlloc
547 {
548  T *m_Obj;
549  mutable refcount m_rc;
550 public:
551  typedef T content_type;
552 
553  PQAlloc() throw () : m_Obj(0), m_rc() {}
554  PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
555  ~PQAlloc() throw () { loseref(); }
556 
557  PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
558 
560 
562  explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
563 
564  void swap(PQAlloc &rhs) throw ()
565  {
566  PQAlloc tmp(*this);
567  *this = rhs;
568  rhs = tmp;
569  }
570 
571  //PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
572 
574  operator bool() const throw () { return m_Obj != 0; }
575 
577  bool operator!() const throw () { return !m_Obj; }
578 
580 
582  T *operator->() const throw (PGSTD::logic_error)
583  {
584  if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
585  return m_Obj;
586  }
587 
589 
591  T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
592 
594 
596  T *get() const throw () { return m_Obj; }
597 
598  void reset() throw () { loseref(); }
599 
600 private:
601  void makeref(T *p) throw () { m_Obj = p; }
602 
603  void makeref(const PQAlloc &rhs) throw ()
604  {
605  m_Obj = rhs.m_Obj;
606  m_rc.makeref(rhs.m_rc);
607  }
608 
610  void loseref() throw ()
611  {
612  if (m_rc.loseref() && m_Obj) DELETER(m_Obj);
613  m_Obj = 0;
614  }
615 
616  void redoref(const PQAlloc &rhs) throw ()
617  { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
618  void redoref(T *obj) throw ()
619  { if (obj != m_Obj) { loseref(); makeref(obj); } }
620 };
621 
622 #endif // PQXX_HAVE_SHARED_PTR
623 
624 
625 template<typename T> class scoped_array
626 {
627  T *m_ptr;
628 public:
629  typedef size_t size_type;
630  typedef long difference_type;
631 
632  scoped_array() : m_ptr(0) {}
633  explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
634  explicit scoped_array(T *t) : m_ptr(t) {}
635  ~scoped_array() { delete [] m_ptr; }
636 
637  T *get() const throw () { return m_ptr; }
638  T &operator*() const throw () { return *m_ptr; }
639  template<typename INDEX> T &operator[](INDEX i) const throw ()
640  { return m_ptr[i]; }
641 
642  scoped_array &operator=(T *t) throw ()
643  {
644  if (t != m_ptr)
645  {
646  delete [] m_ptr;
647  m_ptr = t;
648  }
649  return *this;
650  }
651 
652 private:
654  scoped_array(const scoped_array &);
656 };
657 
658 
659 class PQXX_LIBEXPORT namedclass
660 {
661 public:
662  namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
663  m_Classname(Classname),
664  m_Name(Name)
665  {
666  }
667 
668  const PGSTD::string &name() const throw () { return m_Name; } //[t1]
669  const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
670  PGSTD::string description() const;
671 
672 private:
673  PGSTD::string m_Classname, m_Name;
674 };
675 
676 
677 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
678 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
679 
680 
682 
685 template<typename GUEST>
686 class unique
687 {
688 public:
689  unique() : m_Guest(0) {}
690 
691  GUEST *get() const throw () { return m_Guest; }
692 
693  void Register(GUEST *G)
694  {
695  CheckUniqueRegistration(G, m_Guest);
696  m_Guest = G;
697  }
698 
699  void Unregister(GUEST *G)
700  {
701  CheckUniqueUnregistration(G, m_Guest);
702  m_Guest = 0;
703  }
704 
705 private:
706  GUEST *m_Guest;
707 
709  unique(const unique &);
711  unique &operator=(const unique &);
712 };
713 
715 
718 void PQXX_LIBEXPORT sleep_seconds(int);
719 
721 typedef const char *cstring;
722 
724 
733 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
734  throw ();
735 
736 
738 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
739 
740 } // namespace internal
741 } // namespace pqxx
742 
743 #endif
744