libpqxx  5.0
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-2016, 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 <memory>
26 #include <stdexcept>
27 #include <string>
28 #include <typeinfo>
29 #include <vector>
30 
31 #include "pqxx/strconv"
32 
33 
256 namespace pqxx {}
258 
259 #include <pqxx/internal/libpq-forward.hxx>
260 
261 
262 namespace pqxx
263 {
265 
267 struct PQXX_LIBEXPORT thread_safety_model
268 {
270 
278 
280 
288 
290 
294 
296 
302 
304 
311 
313  std::string description;
314 };
315 
317 PQXX_LIBEXPORT thread_safety_model describe_thread_safety() PQXX_NOEXCEPT;
318 
320 const oid oid_none = 0;
321 
323 
345 template<typename T=std::string, typename CONT=std::vector<T> >
346 class items : public CONT
347 {
348 public:
350  items() : CONT() {} //[t0]
352  explicit items(const T &t) : CONT() { this->push_back(t); } //[t0]
353  items(const T &t1, const T &t2) : CONT() //[t0]
354  { this->push_back(t1); this->push_back(t2); }
355  items(const T &t1, const T &t2, const T &t3) : CONT() //[t0]
356  { this->push_back(t1); this->push_back(t2); this->push_back(t3); }
357  items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[t0]
358  {
359  this->push_back(t1);
360  this->push_back(t2);
361  this->push_back(t3);
362  this->push_back(t4);
363  }
364  items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[t0]
365  {
366  this->push_back(t1);
367  this->push_back(t2);
368  this->push_back(t3);
369  this->push_back(t4);
370  this->push_back(t5);
371  }
373  items(const CONT &c) : CONT(c) {} //[t0]
374 
376  items &operator()(const T &t) //[t0]
377  {
378  this->push_back(t);
379  return *this;
380  }
381 };
382 
383 
384 namespace internal
385 {
386 // TODO: Does standard library provide a ready-made version of this?
388 template<typename ITER> struct dereference
389 {
390  typename ITER::value_type operator()(ITER i) const { return *i; }
391 };
392 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
393 } // namespace internal
394 
395 
397 
403 template<typename ITER, typename ACCESS> inline
404 std::string separated_list(const std::string &sep, //[t0]
405  ITER begin,
406  ITER end,
407  ACCESS access)
408 {
409  std::string result;
410  if (begin != end)
411  {
412  result = to_string(access(begin));
413  for (++begin; begin != end; ++begin)
414  {
415  result += sep;
416  result += to_string(access(begin));
417  }
418  }
419  return result;
420 }
421 
426 
428 template<typename ITER> inline std::string
429 separated_list(const std::string &sep, ITER begin, ITER end) //[t0]
430  { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
431 
432 
434 template<typename OBJ> inline std::string
435 separated_list(const std::string &sep, OBJ *begin, OBJ *end) //[t0]
436  { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
437 
438 
440 template<typename CONTAINER> inline std::string
441 separated_list(const std::string &sep, const CONTAINER &c) //[t10]
442  { return separated_list(sep, c.begin(), c.end()); }
444 
446 
455 namespace internal
456 {
457 typedef unsigned long result_size_type;
459 } // namespace internal
460 
461 
462 namespace internal
463 {
464 PQXX_LIBEXPORT void freepqmem(const void *) PQXX_NOEXCEPT;
465 template<typename P> inline void freepqmem_templated(P *p) PQXX_NOEXCEPT
466 {
467  freepqmem(p);
468 }
469 
470 PQXX_LIBEXPORT void freemallocmem(const void *) PQXX_NOEXCEPT;
471 template<typename P> inline void freemallocmem_templated(P *p) PQXX_NOEXCEPT
472 {
473  freemallocmem(p);
474 }
475 
476 
477 #ifdef PQXX_HAVE_SHARED_PTR
478 
480 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
481  class PQAlloc
482 {
483 public:
484  typedef T content_type;
485  PQAlloc() PQXX_NOEXCEPT : m_ptr() {}
486  PQAlloc(const PQAlloc &rhs) PQXX_NOEXCEPT : m_ptr(rhs.m_ptr) {}
487  explicit PQAlloc(T *t) : m_ptr(t, DELETER) {}
488 
489  T *get() const PQXX_NOEXCEPT { return m_ptr.get(); }
490  PQAlloc &operator=(const PQAlloc &rhs) PQXX_NOEXCEPT
491  {
492  m_ptr = rhs.m_ptr;
493  return *this;
494  }
495 
496 #if __cplusplus >= 201103L
497  PQAlloc(PQAlloc &&) =default;
498  PQAlloc &operator=(PQAlloc &&) =default;
499 #endif
500 
501  T *operator->() const PQXX_NOEXCEPT { return m_ptr.get(); }
502  T &operator*() const PQXX_NOEXCEPT { return *m_ptr; }
503  void reset() PQXX_NOEXCEPT { m_ptr.reset(); }
504  void swap(PQAlloc &other) PQXX_NOEXCEPT { m_ptr.swap(other.m_ptr); }
505 
506 private:
507  std::shared_ptr<T> m_ptr;
508 };
509 
510 #else // !PQXX_HAVE_SHARED_PTR
511 
514 class PQXX_LIBEXPORT refcount
515 {
516  refcount *volatile m_l, *volatile m_r;
517 
518 public:
519  refcount();
520  ~refcount();
521 
523  void makeref(refcount &) PQXX_NOEXCEPT;
524 
526  bool loseref() PQXX_NOEXCEPT;
527 
528 private:
530  refcount(const refcount &);
532  refcount &operator=(const refcount &);
533 };
534 
535 
537 
550 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
551 class PQAlloc
552 {
553  T *m_Obj;
554  mutable refcount m_rc;
555 public:
556  typedef T content_type;
557 
558  PQAlloc() PQXX_NOEXCEPT : m_Obj(0), m_rc() {}
559  PQAlloc(const PQAlloc &rhs) PQXX_NOEXCEPT : m_Obj(0), m_rc() { makeref(rhs); }
560  ~PQAlloc() PQXX_NOEXCEPT { loseref(); }
561 
562  PQAlloc &operator=(const PQAlloc &rhs) PQXX_NOEXCEPT
563  {redoref(rhs); return *this;}
564 
566 
568  explicit PQAlloc(T *obj) PQXX_NOEXCEPT : m_Obj(obj), m_rc() {}
569 
570  void swap(PQAlloc &rhs) PQXX_NOEXCEPT
571  {
572  PQAlloc tmp(*this);
573  *this = rhs;
574  rhs = tmp;
575  }
576 
578  operator bool() const PQXX_NOEXCEPT { return m_Obj != 0; }
579 
581  bool operator!() const PQXX_NOEXCEPT { return !m_Obj; }
582 
584 
586  T *operator->() const
587  {
588  if (!m_Obj) throw std::logic_error("Null pointer dereferenced");
589  return m_Obj;
590  }
591 
593 
595  T &operator*() const { return *operator->(); }
596 
598 
600  T *get() const PQXX_NOEXCEPT { return m_Obj; }
601 
602  void reset() PQXX_NOEXCEPT { loseref(); }
603 
604 private:
605  void makeref(T *p) PQXX_NOEXCEPT { m_Obj = p; }
606 
607  void makeref(const PQAlloc &rhs) PQXX_NOEXCEPT
608  {
609  m_Obj = rhs.m_Obj;
610  m_rc.makeref(rhs.m_rc);
611  }
612 
614  void loseref() PQXX_NOEXCEPT
615  {
616  if (m_rc.loseref() && m_Obj) DELETER(m_Obj);
617  m_Obj = 0;
618  }
619 
620  void redoref(const PQAlloc &rhs) PQXX_NOEXCEPT
621  { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
622  void redoref(T *obj) PQXX_NOEXCEPT
623  { if (obj != m_Obj) { loseref(); makeref(obj); } }
624 };
625 
626 #endif // PQXX_HAVE_SHARED_PTR
627 
628 
629 class PQXX_LIBEXPORT namedclass
630 {
631 public:
632  namedclass(const std::string &Classname, const std::string &Name="") :
633  m_Classname(Classname),
634  m_Name(Name)
635  {
636  }
637 
638  const std::string &name() const PQXX_NOEXCEPT { return m_Name; } //[t1]
639  const std::string &classname() const PQXX_NOEXCEPT //[t73]
640  {return m_Classname;}
641  std::string description() const;
642 
643 private:
644  std::string m_Classname, m_Name;
645 };
646 
647 
648 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
649 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
650 
651 
653 
656 template<typename GUEST>
657 class unique
658 {
659 public:
660  unique() : m_Guest(0) {}
661 
662  GUEST *get() const PQXX_NOEXCEPT { return m_Guest; }
663 
664  void Register(GUEST *G)
665  {
666  CheckUniqueRegistration(G, m_Guest);
667  m_Guest = G;
668  }
669 
670  void Unregister(GUEST *G)
671  {
672  CheckUniqueUnregistration(G, m_Guest);
673  m_Guest = 0;
674  }
675 
676 private:
677  GUEST *m_Guest;
678 
680  unique(const unique &);
682  unique &operator=(const unique &);
683 };
684 
686 
689 PQXX_LIBEXPORT void sleep_seconds(int);
690 
692 typedef const char *cstring;
693 
695 
704 PQXX_LIBEXPORT cstring strerror_wrapper(int err, char buf[], std::size_t len)
705  PQXX_NOEXCEPT;
706 
707 
709 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
710 
711 
713 template<typename T> inline std::ptrdiff_t distance(T first, T last)
714 {
715 #ifdef PQXX_HAVE_DISTANCE
716  return std::distance(first, last);
717 #else
718  // Naive implementation. All we really need for now.
719  std::ptrdiff_t d;
720  for (d=0; first != last; ++d) ++first;
721  return d;
722 #endif
723 }
724 
725 } // namespace internal
726 } // namespace pqxx
727 
728 #endif
729 
const oid oid_none
The &quot;null&quot; oid.
Definition: util.hxx:320
std::string separated_list(const std::string &sep, ITER begin, ITER end, ACCESS access)
Access iterators using ACCESS functor, returning separator-separated list.
Definition: util.hxx:404
long result_difference_type
Definition: util.hxx:458
Container of items with easy contents initialization and string rendering.
Definition: util.hxx:346
void sleep_seconds(int)
Sleep for the given number of seconds.
Definition: util.cxx:192
void swap(PQAlloc &rhs) PQXX_NOEXCEPT
Definition: util.hxx:570
void freemallocmem_templated(P *p) PQXX_NOEXCEPT
Definition: util.hxx:471
std::ptrdiff_t distance(T first, T last)
Wrapper for std::distance; not all platforms have std::distance().
Definition: util.hxx:713
const char sql_rollback_work[]
Definition: util.cxx:53
void makeref(refcount &) PQXX_NOEXCEPT
Create additional reference based on existing refcount object.
Definition: util.cxx:111
PQAlloc(const PQAlloc &rhs) PQXX_NOEXCEPT
Definition: util.hxx:559
items & operator()(const T &t)
Add element to items list.
Definition: util.hxx:376
Functor: dereference iterator.
Definition: util.hxx:388
const std::string & name() const PQXX_NOEXCEPT
Definition: util.hxx:638
bool safe_result_copy
Are copies of pqxx::result and pqxx::binarystring objects thread-safe?
Definition: util.hxx:301
items(const T &t)
Create items list with one element.
Definition: util.hxx:352
PQAlloc(T *obj) PQXX_NOEXCEPT
Assume ownership of a pointer.
Definition: util.hxx:568
bool safe_query_cancel
Is canceling queries thread-safe?
Definition: util.hxx:293
void Register(GUEST *G)
Definition: util.hxx:664
bool have_safe_strerror
Does standard C library have a thread-safe alternative to strerror?
Definition: util.hxx:277
void freemallocmem(const void *) PQXX_NOEXCEPT
Definition: util.cxx:186
const char * cstring
Work around problem with library export directives and pointers.
Definition: util.hxx:692
void freepqmem_templated(P *p) PQXX_NOEXCEPT
Definition: util.hxx:465
items(const T &t1, const T &t2, const T &t3)
Definition: util.hxx:355
bool operator!() const PQXX_NOEXCEPT
Is this pointer null?
Definition: util.hxx:581
Descriptor of library&#39;s thread-safety model.
Definition: util.hxx:267
bool safe_libpq
Is the underlying libpq build thread-safe?
Definition: util.hxx:287
T * operator->() const
Dereference pointer.
Definition: util.hxx:586
bool loseref() PQXX_NOEXCEPT
Drop this reference; return whether we were the last reference.
Definition: util.cxx:120
items(const CONT &c)
Copy container.
Definition: util.hxx:373
namedclass(const std::string &Classname, const std::string &Name="")
Definition: util.hxx:632
items(const T &t1, const T &t2, const T &t3, const T &t4, const T &t5)
Definition: util.hxx:364
cstring strerror_wrapper(int err, char buf[], std::size_t len) PQXX_NOEXCEPT
Human-readable description for error code, possibly using given buffer.
Definition: util.cxx:240
ITER::value_type operator()(ITER i) const
Definition: util.hxx:390
std::string description
A human-readable description of any thread-safety issues.
Definition: util.hxx:313
T & operator*() const
Dereference pointer.
Definition: util.hxx:595
~PQAlloc() PQXX_NOEXCEPT
Definition: util.hxx:560
Definition: util.hxx:392
PQAlloc() PQXX_NOEXCEPT
Definition: util.hxx:558
thread_safety_model describe_thread_safety() PQXX_NOEXCEPT
Describe thread safety available in this build.
Definition: util.cxx:56
Definition: util.hxx:514
bool safe_kerberos
Is Kerberos thread-safe?
Definition: util.hxx:310
unique()
Definition: util.hxx:660
items()
Create empty items list.
Definition: util.hxx:350
unsigned long result_size_type
Definition: util.hxx:457
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old)
Definition: util.cxx:164
T content_type
Definition: util.hxx:556
void freepqmem(const void *) PQXX_NOEXCEPT
Definition: util.cxx:180
const char sql_commit_work[]
Definition: util.cxx:52
PQAlloc & operator=(const PQAlloc &rhs) PQXX_NOEXCEPT
Definition: util.hxx:562
Ensure proper opening/closing of GUEST objects related to a &quot;host&quot; object.
Definition: util.hxx:657
Definition: util.hxx:629
const std::string & classname() const PQXX_NOEXCEPT
Definition: util.hxx:639
const char sql_begin_work[]
Commonly used SQL commands.
Definition: util.cxx:51
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old)
Definition: util.cxx:149
items(const T &t1, const T &t2, const T &t3, const T &t4)
Definition: util.hxx:357
void Unregister(GUEST *G)
Definition: util.hxx:670
Result set containing data returned by a query or command.
Definition: result.hxx:78
items(const T &t1, const T &t2)
Definition: util.hxx:353
T operator()(T *i) const
Definition: util.hxx:392
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.hxx:464
Reference-counted smart pointer to libpq-allocated object.
Definition: util.hxx:551
void reset() PQXX_NOEXCEPT
Definition: util.hxx:602