libpqxx  4.0.1
tuple.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/result.hxx
5  *
6  * DESCRIPTION
7  * definitions for the pqxx::result class and support classes.
8  * pqxx::result represents the set of result tuples from a database query
9  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/tuple instead.
10  *
11  * Copyright (c) 2001-2011, Jeroen T. Vermeulen <jtv@xs4all.nl>
12  *
13  * See COPYING for copyright license. If you did not receive a file called
14  * COPYING with this source code, please notify the distributor of this mistake,
15  * or contact the author.
16  *
17  *-------------------------------------------------------------------------
18  */
19 #ifndef PQXX_H_TUPLE
20 #define PQXX_H_TUPLE
21 
22 #include "pqxx/compiler-public.hxx"
23 #include "pqxx/compiler-internal-pre.hxx"
24 
25 #include "pqxx/except"
26 #include "pqxx/field"
27 
28 
29 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
30  */
31 
32 namespace pqxx
33 {
34 class const_tuple_iterator;
35 class const_reverse_tuple_iterator;
36 class result;
37 class range_error;
38 
39 
41 
52 class PQXX_LIBEXPORT tuple
53 {
54 public:
59  typedef field reference;
63 
65  tuple(const result *r, size_t i) throw ();
66 
67  ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1]
68 
73  bool PQXX_PURE operator==(const tuple &) const throw (); //[t75]
74  bool operator!=(const tuple &rhs) const throw () //[t75]
75  { return !operator==(rhs); }
77 
78  const_iterator begin() const throw (); //[t82]
79  const_iterator end() const throw (); //[t82]
80 
85  reference front() const throw (); //[t74]
86  reference back() const throw (); //[t75]
87 
88  const_reverse_tuple_iterator rbegin() const; //[t82]
89  const_reverse_tuple_iterator rend() const; //[t82]
90 
91  reference operator[](size_type) const throw (); //[t11]
92  reference operator[](int) const throw (); //[t2]
93  reference operator[](const char[]) const; //[t11]
94  reference operator[](const PGSTD::string &) const; //[t11]
95  reference at(size_type) const throw (pqxx::range_error); //[t11]
96  reference at(int) const throw (pqxx::range_error); //[t11]
97  reference at(const char[]) const; //[t11]
98  reference at(const PGSTD::string &) const; //[t11]
100 
101  size_type size() const throw () //[t11]
102  { return m_End-m_Begin; }
103 
104  void swap(tuple &) throw (); //[t11]
105 
106  size_t rownumber() const throw () { return m_Index; } //[t11]
107 
112 
113  size_type column_number(const PGSTD::string &ColName) const //[t30]
114  { return column_number(ColName.c_str()); }
115 
117  size_type column_number(const char[]) const; //[t30]
118 
120  oid column_type(size_type) const; //[t7]
121 
123  oid column_type(int ColNum) const //[t7]
124  { return column_type(size_type(ColNum)); }
125 
127  oid column_type(const PGSTD::string &ColName) const //[t7]
128  { return column_type(column_number(ColName)); }
129 
131  oid column_type(const char ColName[]) const //[t7]
132  { return column_type(column_number(ColName)); }
133 
135  oid column_table(size_type ColNum) const; //[t2]
136 
138  oid column_table(int ColNum) const //[t2]
139  { return column_table(size_type(ColNum)); }
141  oid column_table(const PGSTD::string &ColName) const //[t2]
142  { return column_table(column_number(ColName)); }
143 
145 
155  size_type table_column(size_type) const; //[t93]
156 
158  size_type table_column(int ColNum) const //[t93]
159  { return table_column(size_type(ColNum)); }
160 
162  size_type table_column(const PGSTD::string &ColName) const //[t93]
163  { return table_column(column_number(ColName)); }
165 
166  size_t num() const { return rownumber(); } //[t1]
167 
180  tuple slice(size_type Begin, size_type End) const;
181 
182  // Is this an empty slice?
183  bool PQXX_PURE empty() const throw ();
184 
185 protected:
186  friend class field;
187  const result *m_Home;
188  size_t m_Index;
189  size_type m_Begin;
190  size_type m_End;
191 
192 private:
193  // Not allowed:
194  tuple();
195 };
196 
197 
199 class PQXX_LIBEXPORT const_tuple_iterator :
200  public PGSTD::iterator<PGSTD::random_access_iterator_tag,
201  const field,
202  tuple::size_type>,
203  public field
204 {
205  typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
206  const field,
207  tuple::size_type> it;
208 public:
209  using it::pointer;
212  typedef field reference;
213 
214  const_tuple_iterator(const tuple &T, tuple::size_type C) throw () : //[t82]
215  field(T, C) {}
216  const_tuple_iterator(const field &F) throw () : field(F) {} //[t82]
217 
222  pointer operator->() const { return this; } //[t82]
223  reference operator*() const { return field(*this); } //[t82]
225 
230  const_tuple_iterator operator++(int); //[t82]
231  const_tuple_iterator &operator++() { ++m_col; return *this; } //[t82]
232  const_tuple_iterator operator--(int); //[t82]
233  const_tuple_iterator &operator--() { --m_col; return *this; } //[t82]
234 
235  const_tuple_iterator &operator+=(difference_type i) //[t82]
236  { m_col = size_type(difference_type(m_col) + i); return *this; }
237  const_tuple_iterator &operator-=(difference_type i) //[t82]
238  { m_col = size_type(difference_type(m_col) - i); return *this; }
240 
245  bool operator==(const const_tuple_iterator &i) const //[t82]
246  {return col()==i.col();}
247  bool operator!=(const const_tuple_iterator &i) const //[t82]
248  {return col()!=i.col();}
249  bool operator<(const const_tuple_iterator &i) const //[t82]
250  {return col()<i.col();}
251  bool operator<=(const const_tuple_iterator &i) const //[t82]
252  {return col()<=i.col();}
253  bool operator>(const const_tuple_iterator &i) const //[t82]
254  {return col()>i.col();}
255  bool operator>=(const const_tuple_iterator &i) const //[t82]
256  {return col()>=i.col();}
258 
263  inline const_tuple_iterator operator+(difference_type) const; //[t82]
264 
265  friend const_tuple_iterator operator+( //[t82]
266  difference_type,
268 
269  inline const_tuple_iterator operator-(difference_type) const; //[t82]
270  inline difference_type operator-(const_tuple_iterator) const; //[t82]
272 };
273 
274 
277 {
278 public:
281  using iterator_type::iterator_category;
283  using iterator_type::pointer;
284 #ifndef _MSC_VER
285  using iterator_type::value_type;
287 #else
288  // Workaround for Visual C++.NET 2003, which has access problems
289  typedef field value_type;
290  typedef const field &reference;
291 #endif
292 
295  explicit
296  const_reverse_tuple_iterator(const super &rhs) throw() : //[t82]
297  const_tuple_iterator(rhs) { super::operator--(); }
298 
299  iterator_type PQXX_PURE base() const throw (); //[t82]
300 
305  using iterator_type::operator->; //[t82]
306  using iterator_type::operator*; //[t82]
308 
314  operator=(const const_reverse_tuple_iterator &r) //[t82]
315  { iterator_type::operator=(r); return *this; }
316  const_reverse_tuple_iterator operator++() //[t82]
317  { iterator_type::operator--(); return *this; }
318  const_reverse_tuple_iterator operator++(int); //[t82]
319  const_reverse_tuple_iterator &operator--() //[t82]
320  { iterator_type::operator++(); return *this; }
321  const_reverse_tuple_iterator operator--(int); //[t82]
322  const_reverse_tuple_iterator &operator+=(difference_type i) //[t82]
323  { iterator_type::operator-=(i); return *this; }
324  const_reverse_tuple_iterator &operator-=(difference_type i) //[t82]
325  { iterator_type::operator+=(i); return *this; }
327 
332  const_reverse_tuple_iterator operator+(difference_type i) const //[t82]
333  { return const_reverse_tuple_iterator(base()-i); }
334  const_reverse_tuple_iterator operator-(difference_type i) //[t82]
335  { return const_reverse_tuple_iterator(base()+i); }
336  difference_type
337  operator-(const const_reverse_tuple_iterator &rhs) const //[t82]
338  { return rhs.const_tuple_iterator::operator-(*this); }
340 
345  bool
346  operator==(const const_reverse_tuple_iterator &rhs) const throw () //[t82]
347  { return iterator_type::operator==(rhs); }
348  bool
349  operator!=(const const_reverse_tuple_iterator &rhs) const throw () //[t82]
350  { return !operator==(rhs); }
351 
352  bool operator<(const const_reverse_tuple_iterator &rhs) const //[t82]
353  { return iterator_type::operator>(rhs); }
354  bool operator<=(const const_reverse_tuple_iterator &rhs) const //[t82]
355  { return iterator_type::operator>=(rhs); }
356  bool operator>(const const_reverse_tuple_iterator &rhs) const //[t82]
357  { return iterator_type::operator<(rhs); }
358  bool operator>=(const const_reverse_tuple_iterator &rhs) const //[t82]
359  { return iterator_type::operator<=(rhs); }
361 };
362 
363 
364 inline const_tuple_iterator
365 const_tuple_iterator::operator+(difference_type o) const
366 {
367  return const_tuple_iterator(
368  tuple(home(), idx()),
369  size_type(difference_type(col()) + o));
370 }
371 
374  { return i + o; }
375 
376 inline const_tuple_iterator
377 const_tuple_iterator::operator-(difference_type o) const
378 {
379  return const_tuple_iterator(
380  tuple(home(), idx()),
381  size_type(difference_type(col()) - o));
382 }
383 
386  { return difference_type(num() - i.num()); }
387 
388 
389 } // namespace pqxx
390 
391 
392 /*
393 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
394 Effective C++", points out that it is good style to have any class containing
395 a member of pointer type define a destructor--just to show that it knows what it
396 is doing with the pointer. This helps prevent nasty memory leak / double
397 deletion bugs typically resulting from programmers' omission to deal with such
398 issues in their destructors.
399 
400 The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's
401 style guidelines, and hence necessitates the definition of this destructor,
402 trivial as it may be.
403 */
404 
405 
406 #include "pqxx/compiler-internal-post.hxx"
407 
408 #endif