libpqxx 3.1.1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes

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
290 bool have_strerror_r;
291
293
300 bool safe_libpq;
301
303
306 bool safe_query_cancel;
307
309
314 bool safe_result_copy;
315
317
323 bool safe_kerberos;
324
326 PGSTD::string description;
327 };
328
330 thread_safety_model describe_thread_safety() throw ();
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;
471 typedef long result_difference_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 &);
655 scoped_array &operator=(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