row.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 rows from a database query
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
00010  *
00011  * Copyright (c) 2001-2016, 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_ROW
00020 #define PQXX_H_ROW
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_row_iterator;
00035 class const_reverse_row_iterator;
00036 class result;
00037 class range_error;
00038 
00039 
00041 
00052 class PQXX_LIBEXPORT row
00053 {
00054 public:
00055   typedef row_size_type size_type;
00056   typedef row_difference_type difference_type;
00057   typedef const_row_iterator const_iterator;
00058   typedef const_iterator iterator;
00059   typedef field reference;
00060   typedef const_row_iterator pointer;
00061   typedef const_reverse_row_iterator const_reverse_iterator;
00062   typedef const_reverse_iterator reverse_iterator;
00063 
00065   row(const result *r, size_t i) PQXX_NOEXCEPT;
00066 
00067   ~row() PQXX_NOEXCEPT {} // Yes Scott Meyers, you're absolutely right[1]
00068 
00073   PQXX_PURE bool operator==(const row &) const PQXX_NOEXCEPT;           //[t75]
00074   bool operator!=(const row &rhs) const PQXX_NOEXCEPT                   //[t75]
00075       { return !operator==(rhs); }
00077 
00078   const_iterator begin() const PQXX_NOEXCEPT;                           //[t82]
00079   const_iterator cbegin() const PQXX_NOEXCEPT;
00080   const_iterator end() const PQXX_NOEXCEPT;                             //[t82]
00081   const_iterator cend() const PQXX_NOEXCEPT;
00082 
00087   reference front() const PQXX_NOEXCEPT;                                //[t74]
00088   reference back() const PQXX_NOEXCEPT;                                 //[t75]
00089 
00090   const_reverse_row_iterator rbegin() const;                            //[t82]
00091   const_reverse_row_iterator crbegin() const;
00092   const_reverse_row_iterator rend() const;                              //[t82]
00093   const_reverse_row_iterator crend() const;
00094 
00095   reference operator[](size_type) const PQXX_NOEXCEPT;                  //[t11]
00096   reference operator[](int) const PQXX_NOEXCEPT;                        //[t2]
00100   reference operator[](const char[]) const;                             //[t11]
00104   reference operator[](const std::string &) const;                      //[t11]
00105   reference at(size_type) const;                                        //[t11]
00106   reference at(int) const;                                              //[t11]
00110   reference at(const char[]) const;                                     //[t11]
00114   reference at(const std::string &) const;                              //[t11]
00116 
00117   size_type size() const PQXX_NOEXCEPT                                  //[t11]
00118                                                      { return m_End-m_Begin; }
00119 
00120   void swap(row &) PQXX_NOEXCEPT;                                       //[t11]
00121 
00122   size_t rownumber() const PQXX_NOEXCEPT { return m_Index; }                    //[t11]
00123 
00128 
00129   size_type column_number(const std::string &ColName) const             //[t30]
00130       { return column_number(ColName.c_str()); }
00131 
00133   size_type column_number(const char[]) const;                          //[t30]
00134 
00136   oid column_type(size_type) const;                                     //[t7]
00137 
00139   oid column_type(int ColNum) const                                     //[t7]
00140       { return column_type(size_type(ColNum)); }
00141 
00143   oid column_type(const std::string &ColName) const                     //[t7]
00144       { return column_type(column_number(ColName)); }
00145 
00147   oid column_type(const char ColName[]) const                           //[t7]
00148       { return column_type(column_number(ColName)); }
00149 
00151   oid column_table(size_type ColNum) const;                             //[t2]
00152 
00154   oid column_table(int ColNum) const                                    //[t2]
00155       { return column_table(size_type(ColNum)); }
00157   oid column_table(const std::string &ColName) const                    //[t2]
00158       { return column_table(column_number(ColName)); }
00159 
00161 
00168   size_type table_column(size_type) const;                              //[t93]
00169 
00171   size_type table_column(int ColNum) const                              //[t93]
00172       { return table_column(size_type(ColNum)); }
00173 
00175   size_type table_column(const std::string &ColName) const              //[t93]
00176       { return table_column(column_number(ColName)); }
00178 
00179   size_t num() const { return rownumber(); }                            //[t1]
00180 
00193   row slice(size_type Begin, size_type End) const;
00194 
00195   // Is this an empty slice?
00196   PQXX_PURE bool empty() const PQXX_NOEXCEPT;
00197 
00198 protected:
00199   friend class field;
00200   const result *m_Home;
00201   size_t m_Index;
00202   size_type m_Begin;
00203   size_type m_End;
00204 
00205 private:
00206   // Not allowed:
00207   row() PQXX_DELETED_OP;
00208 };
00209 
00210 
00212 class PQXX_LIBEXPORT const_row_iterator :
00213   public std::iterator<std::random_access_iterator_tag,
00214                        const field,
00215                        row::size_type>,
00216   public field
00217 {
00218   typedef std::iterator<std::random_access_iterator_tag,
00219                         const field,
00220                         row::size_type> it;
00221 public:
00222   using it::pointer;
00223   typedef row::size_type size_type;
00224   typedef row::difference_type difference_type;
00225   typedef field reference;
00226 
00227   const_row_iterator(const row &T, row::size_type C)                    //[t82]
00228         PQXX_NOEXCEPT :
00229     field(T, C) {}
00230   const_row_iterator(const field &F) PQXX_NOEXCEPT : field(F) {}        //[t82]
00231 
00236   pointer operator->() const { return this; }                           //[t82]
00237   reference operator*() const { return field(*this); }                  //[t82]
00239 
00244   const_row_iterator operator++(int);                                   //[t82]
00245   const_row_iterator &operator++() { ++m_col; return *this; }           //[t82]
00246   const_row_iterator operator--(int);                                   //[t82]
00247   const_row_iterator &operator--() { --m_col; return *this; }           //[t82]
00248 
00249   const_row_iterator &operator+=(difference_type i)                     //[t82]
00250       { m_col = size_type(difference_type(m_col) + i); return *this; }
00251   const_row_iterator &operator-=(difference_type i)                     //[t82]
00252       { m_col = size_type(difference_type(m_col) - i); return *this; }
00254 
00259   bool operator==(const const_row_iterator &i) const                    //[t82]
00260       {return col()==i.col();}
00261   bool operator!=(const const_row_iterator &i) const                    //[t82]
00262       {return col()!=i.col();}
00263   bool operator<(const const_row_iterator &i) const                     //[t82]
00264       {return col()<i.col();}
00265   bool operator<=(const const_row_iterator &i) const                    //[t82]
00266       {return col()<=i.col();}
00267   bool operator>(const const_row_iterator &i) const                     //[t82]
00268       {return col()>i.col();}
00269   bool operator>=(const const_row_iterator &i) const                    //[t82]
00270       {return col()>=i.col();}
00272 
00277   inline const_row_iterator operator+(difference_type) const;           //[t82]
00278 
00279   friend const_row_iterator operator+(                                  //[t82]
00280         difference_type,
00281         const_row_iterator);
00282 
00283   inline const_row_iterator operator-(difference_type) const;           //[t82]
00284   inline difference_type operator-(const_row_iterator) const;           //[t82]
00286 };
00287 
00288 
00290 class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator
00291 {
00292 public:
00293   typedef const_row_iterator super;
00294   typedef const_row_iterator iterator_type;
00295   using iterator_type::iterator_category;
00296   using iterator_type::difference_type;
00297   using iterator_type::pointer;
00298 #ifndef _MSC_VER
00299   using iterator_type::value_type;
00300   using iterator_type::reference;
00301 #else
00302   // Workaround for Visual C++.NET 2003, which has access problems
00303   typedef field value_type;
00304   typedef const field &reference;
00305 #endif
00306 
00307   const_reverse_row_iterator(const const_reverse_row_iterator &r) :     //[t82]
00308     const_row_iterator(r) {}
00309   explicit
00310     const_reverse_row_iterator(const super &rhs) PQXX_NOEXCEPT :        //[t82]
00311       const_row_iterator(rhs) { super::operator--(); }
00312 
00313   PQXX_PURE iterator_type base() const PQXX_NOEXCEPT;                   //[t82]
00314 
00319   using iterator_type::operator->;                                      //[t82]
00320   using iterator_type::operator*;                                       //[t82]
00322 
00327   const_reverse_row_iterator &
00328     operator=(const const_reverse_row_iterator &r)                      //[t82]
00329       { iterator_type::operator=(r); return *this; }
00330   const_reverse_row_iterator operator++()                               //[t82]
00331       { iterator_type::operator--(); return *this; }
00332   const_reverse_row_iterator operator++(int);                           //[t82]
00333   const_reverse_row_iterator &operator--()                              //[t82]
00334       { iterator_type::operator++(); return *this; }
00335   const_reverse_row_iterator operator--(int);                           //[t82]
00336   const_reverse_row_iterator &operator+=(difference_type i)             //[t82]
00337       { iterator_type::operator-=(i); return *this; }
00338   const_reverse_row_iterator &operator-=(difference_type i)             //[t82]
00339       { iterator_type::operator+=(i); return *this; }
00341 
00346   const_reverse_row_iterator operator+(difference_type i) const         //[t82]
00347       { return const_reverse_row_iterator(base()-i); }
00348   const_reverse_row_iterator operator-(difference_type i)               //[t82]
00349       { return const_reverse_row_iterator(base()+i); }
00350   difference_type
00351     operator-(const const_reverse_row_iterator &rhs) const              //[t82]
00352       { return rhs.const_row_iterator::operator-(*this); }
00354 
00359   bool operator==(const const_reverse_row_iterator &rhs)                //[t82]
00360         const PQXX_NOEXCEPT
00361       { return iterator_type::operator==(rhs); }
00362   bool operator!=(const const_reverse_row_iterator &rhs)                //[t82]
00363         const PQXX_NOEXCEPT
00364       { return !operator==(rhs); }
00365 
00366   bool operator<(const const_reverse_row_iterator &rhs) const           //[t82]
00367       { return iterator_type::operator>(rhs); }
00368   bool operator<=(const const_reverse_row_iterator &rhs) const          //[t82]
00369       { return iterator_type::operator>=(rhs); }
00370   bool operator>(const const_reverse_row_iterator &rhs) const           //[t82]
00371       { return iterator_type::operator<(rhs); }
00372   bool operator>=(const const_reverse_row_iterator &rhs) const          //[t82]
00373       { return iterator_type::operator<=(rhs); }
00375 };
00376 
00377 
00378 inline const_row_iterator
00379 const_row_iterator::operator+(difference_type o) const
00380 {
00381   return const_row_iterator(
00382         row(home(), idx()),
00383         size_type(difference_type(col()) + o));
00384 }
00385 
00386 inline const_row_iterator
00387 operator+(const_row_iterator::difference_type o, const_row_iterator i)
00388         { return i + o; }
00389 
00390 inline const_row_iterator
00391 const_row_iterator::operator-(difference_type o) const
00392 {
00393   return const_row_iterator(
00394         row(home(), idx()),
00395         size_type(difference_type(col()) - o));
00396 }
00397 
00398 inline const_row_iterator::difference_type
00399 const_row_iterator::operator-(const_row_iterator i) const
00400         { return difference_type(num() - i.num()); }
00401 
00402 
00403 } // namespace pqxx
00404 
00405 
00406 /*
00407 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
00408 Effective C++", points out that it is good style to have any class containing
00409 a member of pointer type define a destructor--just to show that it knows what it
00410 is doing with the pointer.  This helps prevent nasty memory leak / double
00411 deletion bugs typically resulting from programmers' omission to deal with such
00412 issues in their destructors.
00413 
00414 The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's
00415 style guidelines, and hence necessitates the definition of this destructor,
00416 trivial as it may be.
00417 */
00418 
00419 
00420 #include "pqxx/compiler-internal-post.hxx"
00421 
00422 #endif

Generated on 17 Mar 2017 for libpqxx by  doxygen 1.6.1