libpqxx 4.0
tuple.hxx
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/result.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definitions for the pqxx::result class and support classes.
00008  *   pqxx::result represents the set of result tuples from a database query
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/tuple instead.
00010  *
00011  * Copyright (c) 2001-2011, Jeroen T. Vermeulen <jtv@xs4all.nl>
00012  *
00013  * See COPYING for copyright license.  If you did not receive a file called
00014  * COPYING with this source code, please notify the distributor of this mistake,
00015  * or contact the author.
00016  *
00017  *-------------------------------------------------------------------------
00018  */
00019 #ifndef PQXX_H_TUPLE
00020 #define PQXX_H_TUPLE
00021 
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024 
00025 #include "pqxx/except"
00026 #include "pqxx/field"
00027 
00028 
00029 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00030  */
00031 
00032 namespace pqxx
00033 {
00034 class const_tuple_iterator;
00035 class const_reverse_tuple_iterator;
00036 class result;
00037 
00038 
00040 
00051 class PQXX_LIBEXPORT tuple
00052 {
00053 public:
00054   typedef tuple_size_type size_type;
00055   typedef tuple_difference_type difference_type;
00056   typedef const_tuple_iterator const_iterator;
00057   typedef const_iterator iterator;
00058   typedef field reference;
00059   typedef const_tuple_iterator pointer;
00060   typedef const_reverse_tuple_iterator const_reverse_iterator;
00061   typedef const_reverse_iterator reverse_iterator;
00062 
00064   tuple(const result *r, size_t i) throw ();
00065 
00066   ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1]
00067 
00072   bool PQXX_PURE operator==(const tuple &) const throw ();              //[t75]
00073   bool operator!=(const tuple &rhs) const throw ()                      //[t75]
00074       { return !operator==(rhs); }
00076 
00077   const_iterator begin() const throw ();                                //[t82]
00078   const_iterator end() const throw ();                                  //[t82]
00079 
00084   reference front() const throw ();                                     //[t74]
00085   reference back() const throw ();                                      //[t75]
00086 
00087   const_reverse_tuple_iterator rbegin() const;                          //[t82]
00088   const_reverse_tuple_iterator rend() const;                            //[t82]
00089 
00090   reference operator[](size_type) const throw ();                       //[t11]
00091   reference operator[](int) const throw ();                             //[t2]
00092   reference operator[](const char[]) const;                             //[t11]
00093   reference operator[](const PGSTD::string &) const;                    //[t11]
00094   reference at(size_type) const throw (range_error);                    //[t11]
00095   reference at(int) const throw (range_error);                          //[t11]
00096   reference at(const char[]) const;                                     //[t11]
00097   reference at(const PGSTD::string &) const;                            //[t11]
00099 
00100   size_type size() const throw ()                                       //[t11]
00101                                                      { return m_End-m_Begin; }
00102 
00103   void swap(tuple &) throw ();                                          //[t11]
00104 
00105   size_t rownumber() const throw () { return m_Index; }                 //[t11]
00106 
00111 
00112   size_type column_number(const PGSTD::string &ColName) const           //[t30]
00113       { return column_number(ColName.c_str()); }
00114 
00116   size_type column_number(const char[]) const;                          //[t30]
00117 
00119   oid column_type(size_type) const;                                     //[t7]
00120 
00122   oid column_type(int ColNum) const                                     //[t7]
00123       { return column_type(size_type(ColNum)); }
00124 
00126   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00127       { return column_type(column_number(ColName)); }
00128 
00130   oid column_type(const char ColName[]) const                           //[t7]
00131       { return column_type(column_number(ColName)); }
00132 
00134   oid column_table(size_type ColNum) const;                             //[t2]
00135 
00137   oid column_table(int ColNum) const                                    //[t2]
00138       { return column_table(size_type(ColNum)); }
00140   oid column_table(const PGSTD::string &ColName) const          //[t2]
00141       { return column_table(column_number(ColName)); }
00142 
00144 
00154   size_type table_column(size_type) const;                              //[t93]
00155 
00157   size_type table_column(int ColNum) const                              //[t93]
00158       { return table_column(size_type(ColNum)); }
00159 
00161   size_type table_column(const PGSTD::string &ColName) const            //[t93]
00162       { return table_column(column_number(ColName)); }
00164 
00165   size_t num() const { return rownumber(); }                            //[t1]
00166 
00179   tuple slice(size_type Begin, size_type End) const;
00180 
00181   // Is this an empty slice?
00182   bool PQXX_PURE empty() const throw ();
00183 
00184 protected:
00185   friend class field;
00186   const result *m_Home;
00187   size_t m_Index;
00188   size_type m_Begin;
00189   size_type m_End;
00190 
00191 private:
00192   // Not allowed:
00193   tuple();
00194 };
00195 
00196 
00198 class PQXX_LIBEXPORT const_tuple_iterator :
00199   public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00200                          const field,
00201                          tuple::size_type>,
00202   public field
00203 {
00204   typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00205                                 const field,
00206                                 tuple::size_type> it;
00207 public:
00208   using it::pointer;
00209   typedef tuple::size_type size_type;
00210   typedef tuple::difference_type difference_type;
00211   typedef field reference;
00212 
00213   const_tuple_iterator(const tuple &T, tuple::size_type C) throw () :   //[t82]
00214     field(T, C) {}
00215   const_tuple_iterator(const field &F) throw () : field(F) {}           //[t82]
00216 
00221   pointer operator->() const { return this; }                           //[t82]
00222   reference operator*() const { return field(*this); }                  //[t82]
00224 
00229   const_tuple_iterator operator++(int);                                 //[t82]
00230   const_tuple_iterator &operator++() { ++m_col; return *this; }         //[t82]
00231   const_tuple_iterator operator--(int);                                 //[t82]
00232   const_tuple_iterator &operator--() { --m_col; return *this; }         //[t82]
00233 
00234   const_tuple_iterator &operator+=(difference_type i)                   //[t82]
00235       { m_col = size_type(difference_type(m_col) + i); return *this; }
00236   const_tuple_iterator &operator-=(difference_type i)                   //[t82]
00237       { m_col = size_type(difference_type(m_col) - i); return *this; }
00239 
00244   bool operator==(const const_tuple_iterator &i) const                  //[t82]
00245       {return col()==i.col();}
00246   bool operator!=(const const_tuple_iterator &i) const                  //[t82]
00247       {return col()!=i.col();}
00248   bool operator<(const const_tuple_iterator &i) const                   //[t82]
00249       {return col()<i.col();}
00250   bool operator<=(const const_tuple_iterator &i) const                  //[t82]
00251       {return col()<=i.col();}
00252   bool operator>(const const_tuple_iterator &i) const                   //[t82]
00253       {return col()>i.col();}
00254   bool operator>=(const const_tuple_iterator &i) const                  //[t82]
00255       {return col()>=i.col();}
00257 
00262   inline const_tuple_iterator operator+(difference_type) const;         //[t82]
00263 
00264   friend const_tuple_iterator operator+(                                //[t82]
00265         difference_type,
00266         const_tuple_iterator);
00267 
00268   inline const_tuple_iterator operator-(difference_type) const;         //[t82]
00269   inline difference_type operator-(const_tuple_iterator) const;         //[t82]
00271 };
00272 
00273 
00275 class PQXX_LIBEXPORT const_reverse_tuple_iterator : private const_tuple_iterator
00276 {
00277 public:
00278   typedef const_tuple_iterator super;
00279   typedef const_tuple_iterator iterator_type;
00280   using iterator_type::iterator_category;
00281   using iterator_type::difference_type;
00282   using iterator_type::pointer;
00283 #ifndef _MSC_VER
00284   using iterator_type::value_type;
00285   using iterator_type::reference;
00286 #else
00287   // Workaround for Visual C++.NET 2003, which has access problems
00288   typedef field value_type;
00289   typedef const field &reference;
00290 #endif
00291 
00292   const_reverse_tuple_iterator(const const_reverse_tuple_iterator &r) : //[t82]
00293     const_tuple_iterator(r) {}
00294   explicit
00295     const_reverse_tuple_iterator(const super &rhs) throw() :            //[t82]
00296       const_tuple_iterator(rhs) { super::operator--(); }
00297 
00298   iterator_type PQXX_PURE base() const throw ();                        //[t82]
00299 
00304   using iterator_type::operator->;                                      //[t82]
00305   using iterator_type::operator*;                                       //[t82]
00307 
00312   const_reverse_tuple_iterator &
00313     operator=(const const_reverse_tuple_iterator &r)                    //[t82]
00314       { iterator_type::operator=(r); return *this; }
00315   const_reverse_tuple_iterator operator++()                             //[t82]
00316       { iterator_type::operator--(); return *this; }
00317   const_reverse_tuple_iterator operator++(int);                         //[t82]
00318   const_reverse_tuple_iterator &operator--()                            //[t82]
00319       { iterator_type::operator++(); return *this; }
00320   const_reverse_tuple_iterator operator--(int);                         //[t82]
00321   const_reverse_tuple_iterator &operator+=(difference_type i)           //[t82]
00322       { iterator_type::operator-=(i); return *this; }
00323   const_reverse_tuple_iterator &operator-=(difference_type i)           //[t82]
00324       { iterator_type::operator+=(i); return *this; }
00326 
00331   const_reverse_tuple_iterator operator+(difference_type i) const       //[t82]
00332       { return const_reverse_tuple_iterator(base()-i); }
00333   const_reverse_tuple_iterator operator-(difference_type i)             //[t82]
00334       { return const_reverse_tuple_iterator(base()+i); }
00335   difference_type
00336     operator-(const const_reverse_tuple_iterator &rhs) const            //[t82]
00337       { return rhs.const_tuple_iterator::operator-(*this); }
00339 
00344   bool
00345     operator==(const const_reverse_tuple_iterator &rhs) const throw ()  //[t82]
00346       { return iterator_type::operator==(rhs); }
00347   bool
00348     operator!=(const const_reverse_tuple_iterator &rhs) const throw ()  //[t82]
00349       { return !operator==(rhs); }
00350 
00351   bool operator<(const const_reverse_tuple_iterator &rhs) const         //[t82]
00352       { return iterator_type::operator>(rhs); }
00353   bool operator<=(const const_reverse_tuple_iterator &rhs) const        //[t82]
00354       { return iterator_type::operator>=(rhs); }
00355   bool operator>(const const_reverse_tuple_iterator &rhs) const         //[t82]
00356       { return iterator_type::operator<(rhs); }
00357   bool operator>=(const const_reverse_tuple_iterator &rhs) const        //[t82]
00358       { return iterator_type::operator<=(rhs); }
00360 };
00361 
00362 
00363 inline const_tuple_iterator
00364 const_tuple_iterator::operator+(difference_type o) const
00365 {
00366   return const_tuple_iterator(
00367         tuple(home(), idx()),
00368         size_type(difference_type(col()) + o));
00369 }
00370 
00371 inline const_tuple_iterator
00372 operator+(const_tuple_iterator::difference_type o, const_tuple_iterator i)
00373         { return i + o; }
00374 
00375 inline const_tuple_iterator
00376 const_tuple_iterator::operator-(difference_type o) const
00377 {
00378   return const_tuple_iterator(
00379         tuple(home(), idx()),
00380         size_type(difference_type(col()) - o));
00381 }
00382 
00383 inline const_tuple_iterator::difference_type
00384 const_tuple_iterator::operator-(const_tuple_iterator i) const
00385         { return difference_type(num() - i.num()); }
00386 
00387 
00388 } // namespace pqxx
00389 
00390 
00391 /*
00392 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
00393 Effective C++", points out that it is good style to have any class containing
00394 a member of pointer type define a destructor--just to show that it knows what it
00395 is doing with the pointer.  This helps prevent nasty memory leak / double
00396 deletion bugs typically resulting from programmers' omission to deal with such
00397 issues in their destructors.
00398 
00399 The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's
00400 style guidelines, and hence necessitates the definition of this destructor,
00401 trivial as it may be.
00402 */
00403 
00404 
00405 #include "pqxx/compiler-internal-post.hxx"
00406 
00407 #endif