mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-08 22:12:41 +00:00
be7ce4110e
This reverts commit e96515433d
.
390 lines
10 KiB
C++
390 lines
10 KiB
C++
/* Definitions for the pqxx::result class and support classes.
|
|
*
|
|
* pqxx::result represents the set of result rows from a database query.
|
|
*
|
|
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
|
|
*
|
|
* Copyright (c) 2000-2022, Jeroen T. Vermeulen.
|
|
*
|
|
* See COPYING for copyright license. If you did not receive a file called
|
|
* COPYING with this source code, please notify the distributor of this
|
|
* mistake, or contact the author.
|
|
*/
|
|
#ifndef PQXX_H_RESULT_ITERATOR
|
|
#define PQXX_H_RESULT_ITERATOR
|
|
|
|
#include "pqxx/row.hxx"
|
|
|
|
|
|
/* Result iterator.
|
|
*
|
|
* Don't include this header from your own application; it is included for you
|
|
* by other libpqxx headers.
|
|
*/
|
|
|
|
namespace pqxx
|
|
{
|
|
/// Iterator for rows in a result. Use as result::const_iterator.
|
|
/** A result, once obtained, cannot be modified. Therefore there is no
|
|
* plain iterator type for result. However its const_iterator type can be
|
|
* used to inspect its rows without changing them.
|
|
*/
|
|
class PQXX_LIBEXPORT const_result_iterator : public row
|
|
{
|
|
public:
|
|
using iterator_category = std::random_access_iterator_tag;
|
|
using value_type = row const;
|
|
using pointer = row const *;
|
|
using reference = row;
|
|
using size_type = result_size_type;
|
|
using difference_type = result_difference_type;
|
|
|
|
#include "pqxx/internal/ignore-deprecated-pre.hxx"
|
|
/// Create an iterator, but in an unusable state.
|
|
const_result_iterator() noexcept = default;
|
|
/// Copy an iterator.
|
|
const_result_iterator(const_result_iterator const &) noexcept = default;
|
|
/// Move an iterator.
|
|
const_result_iterator(const_result_iterator &&) noexcept = default;
|
|
|
|
/// Begin iterating a @ref row.
|
|
const_result_iterator(row const &t) noexcept : row{t} {}
|
|
#include "pqxx/internal/ignore-deprecated-post.hxx"
|
|
|
|
/**
|
|
* @name Dereferencing operators
|
|
*
|
|
* An iterator "points to" its own row, which is also itself. This makes it
|
|
* easy to address a @ref result as a two-dimensional container, without
|
|
* going through the intermediate step of dereferencing the iterator. It
|
|
* makes the interface similar to C pointer/array semantics.
|
|
*
|
|
* IIRC Alex Stepanov, the inventor of the STL, once remarked that having
|
|
* this as standard behaviour for pointers would be useful in some
|
|
* algorithms. So even if this makes me look foolish, I would seem to be in
|
|
* distinguished company.
|
|
*/
|
|
//@{
|
|
/// Dereference the iterator.
|
|
[[nodiscard]] pointer operator->() const { return this; }
|
|
|
|
#include "pqxx/internal/ignore-deprecated-pre.hxx"
|
|
/// Dereference the iterator.
|
|
[[nodiscard]] reference operator*() const { return *this; }
|
|
#include "pqxx/internal/ignore-deprecated-post.hxx"
|
|
//@}
|
|
|
|
/**
|
|
* @name Field access
|
|
*/
|
|
//@{
|
|
using row::back;
|
|
using row::front;
|
|
using row::operator[];
|
|
using row::at;
|
|
using row::rownumber;
|
|
//@}
|
|
|
|
/**
|
|
* @name Manipulations
|
|
*/
|
|
//@{
|
|
const_result_iterator &operator=(const_result_iterator const &rhs)
|
|
{
|
|
#include "pqxx/internal/ignore-deprecated-pre.hxx"
|
|
row::operator=(rhs);
|
|
#include "pqxx/internal/ignore-deprecated-post.hxx"
|
|
return *this;
|
|
}
|
|
|
|
const_result_iterator &operator=(const_result_iterator &&rhs)
|
|
{
|
|
#include "pqxx/internal/ignore-deprecated-pre.hxx"
|
|
row::operator=(std::move(rhs));
|
|
#include "pqxx/internal/ignore-deprecated-post.hxx"
|
|
return *this;
|
|
}
|
|
|
|
const_result_iterator operator++(int);
|
|
const_result_iterator &operator++()
|
|
{
|
|
++m_index;
|
|
return *this;
|
|
}
|
|
const_result_iterator operator--(int);
|
|
const_result_iterator &operator--()
|
|
{
|
|
--m_index;
|
|
return *this;
|
|
}
|
|
|
|
const_result_iterator &operator+=(difference_type i)
|
|
{
|
|
m_index += i;
|
|
return *this;
|
|
}
|
|
const_result_iterator &operator-=(difference_type i)
|
|
{
|
|
m_index -= i;
|
|
return *this;
|
|
}
|
|
|
|
/// Interchange two iterators in an exception-safe manner.
|
|
void swap(const_result_iterator &other) noexcept
|
|
{
|
|
#include "pqxx/internal/ignore-deprecated-pre.hxx"
|
|
row::swap(other);
|
|
#include "pqxx/internal/ignore-deprecated-post.hxx"
|
|
}
|
|
//@}
|
|
|
|
/**
|
|
* @name Comparisons
|
|
*/
|
|
//@{
|
|
[[nodiscard]] bool operator==(const_result_iterator const &i) const
|
|
{
|
|
return m_index == i.m_index;
|
|
}
|
|
[[nodiscard]] bool operator!=(const_result_iterator const &i) const
|
|
{
|
|
return m_index != i.m_index;
|
|
}
|
|
[[nodiscard]] bool operator<(const_result_iterator const &i) const
|
|
{
|
|
return m_index < i.m_index;
|
|
}
|
|
[[nodiscard]] bool operator<=(const_result_iterator const &i) const
|
|
{
|
|
return m_index <= i.m_index;
|
|
}
|
|
[[nodiscard]] bool operator>(const_result_iterator const &i) const
|
|
{
|
|
return m_index > i.m_index;
|
|
}
|
|
[[nodiscard]] bool operator>=(const_result_iterator const &i) const
|
|
{
|
|
return m_index >= i.m_index;
|
|
}
|
|
//@}
|
|
|
|
/**
|
|
* @name Arithmetic operators
|
|
*/
|
|
//@{
|
|
[[nodiscard]] inline const_result_iterator operator+(difference_type) const;
|
|
friend const_result_iterator
|
|
operator+(difference_type, const_result_iterator const &);
|
|
[[nodiscard]] inline const_result_iterator operator-(difference_type) const;
|
|
[[nodiscard]] inline difference_type
|
|
operator-(const_result_iterator const &) const;
|
|
//@}
|
|
|
|
private:
|
|
friend class pqxx::result;
|
|
const_result_iterator(pqxx::result const *r, result_size_type i) noexcept :
|
|
row{*r, i, r->columns()}
|
|
{}
|
|
};
|
|
|
|
|
|
/// Reverse iterator for result. Use as result::const_reverse_iterator.
|
|
class PQXX_LIBEXPORT const_reverse_result_iterator
|
|
: private const_result_iterator
|
|
{
|
|
public:
|
|
using super = const_result_iterator;
|
|
using iterator_type = const_result_iterator;
|
|
using iterator_type::difference_type;
|
|
using iterator_type::iterator_category;
|
|
using iterator_type::pointer;
|
|
using value_type = iterator_type::value_type;
|
|
using reference = iterator_type::reference;
|
|
|
|
/// Create an iterator, but in an unusable state.
|
|
const_reverse_result_iterator() = default;
|
|
/// Copy an iterator.
|
|
const_reverse_result_iterator(const_reverse_result_iterator const &rhs) =
|
|
default;
|
|
/// Copy a reverse iterator from a regular iterator.
|
|
explicit const_reverse_result_iterator(const_result_iterator const &rhs) :
|
|
const_result_iterator{rhs}
|
|
{
|
|
super::operator--();
|
|
}
|
|
|
|
/// Move a regular iterator into a reverse iterator.
|
|
explicit const_reverse_result_iterator(const_result_iterator const &&rhs) :
|
|
const_result_iterator{std::move(rhs)}
|
|
{
|
|
super::operator--();
|
|
}
|
|
|
|
/// Return the underlying "regular" iterator (as per standard library).
|
|
[[nodiscard]] PQXX_PURE const_result_iterator base() const noexcept;
|
|
|
|
/**
|
|
* @name Dereferencing operators
|
|
*/
|
|
//@{
|
|
/// Dereference iterator.
|
|
using const_result_iterator::operator->;
|
|
/// Dereference iterator.
|
|
using const_result_iterator::operator*;
|
|
//@}
|
|
|
|
/**
|
|
* @name Field access
|
|
*/
|
|
//@{
|
|
using const_result_iterator::back;
|
|
using const_result_iterator::front;
|
|
using const_result_iterator::operator[];
|
|
using const_result_iterator::at;
|
|
using const_result_iterator::rownumber;
|
|
//@}
|
|
|
|
/**
|
|
* @name Manipulations
|
|
*/
|
|
//@{
|
|
const_reverse_result_iterator &
|
|
operator=(const_reverse_result_iterator const &r)
|
|
{
|
|
iterator_type::operator=(r);
|
|
return *this;
|
|
}
|
|
const_reverse_result_iterator &operator=(const_reverse_result_iterator &&r)
|
|
{
|
|
iterator_type::operator=(std::move(r));
|
|
return *this;
|
|
}
|
|
const_reverse_result_iterator &operator++()
|
|
{
|
|
iterator_type::operator--();
|
|
return *this;
|
|
}
|
|
const_reverse_result_iterator operator++(int);
|
|
const_reverse_result_iterator &operator--()
|
|
{
|
|
iterator_type::operator++();
|
|
return *this;
|
|
}
|
|
const_reverse_result_iterator operator--(int);
|
|
const_reverse_result_iterator &operator+=(difference_type i)
|
|
{
|
|
iterator_type::operator-=(i);
|
|
return *this;
|
|
}
|
|
const_reverse_result_iterator &operator-=(difference_type i)
|
|
{
|
|
iterator_type::operator+=(i);
|
|
return *this;
|
|
}
|
|
|
|
void swap(const_reverse_result_iterator &other) noexcept
|
|
{
|
|
const_result_iterator::swap(other);
|
|
}
|
|
//@}
|
|
|
|
/**
|
|
* @name Arithmetic operators
|
|
*/
|
|
//@{
|
|
[[nodiscard]] const_reverse_result_iterator
|
|
operator+(difference_type i) const
|
|
{
|
|
return const_reverse_result_iterator(base() - i);
|
|
}
|
|
[[nodiscard]] const_reverse_result_iterator operator-(difference_type i)
|
|
{
|
|
return const_reverse_result_iterator(base() + i);
|
|
}
|
|
[[nodiscard]] difference_type
|
|
operator-(const_reverse_result_iterator const &rhs) const
|
|
{
|
|
return rhs.const_result_iterator::operator-(*this);
|
|
}
|
|
//@}
|
|
|
|
/**
|
|
* @name Comparisons
|
|
*/
|
|
//@{
|
|
[[nodiscard]] bool
|
|
operator==(const_reverse_result_iterator const &rhs) const noexcept
|
|
{
|
|
return iterator_type::operator==(rhs);
|
|
}
|
|
[[nodiscard]] bool
|
|
operator!=(const_reverse_result_iterator const &rhs) const noexcept
|
|
{
|
|
return not operator==(rhs);
|
|
}
|
|
|
|
[[nodiscard]] bool operator<(const_reverse_result_iterator const &rhs) const
|
|
{
|
|
return iterator_type::operator>(rhs);
|
|
}
|
|
[[nodiscard]] bool operator<=(const_reverse_result_iterator const &rhs) const
|
|
{
|
|
return iterator_type::operator>=(rhs);
|
|
}
|
|
[[nodiscard]] bool operator>(const_reverse_result_iterator const &rhs) const
|
|
{
|
|
return iterator_type::operator<(rhs);
|
|
}
|
|
[[nodiscard]] bool operator>=(const_reverse_result_iterator const &rhs) const
|
|
{
|
|
return iterator_type::operator<=(rhs);
|
|
}
|
|
//@}
|
|
};
|
|
|
|
|
|
inline const_result_iterator
|
|
const_result_iterator::operator+(result::difference_type o) const
|
|
{
|
|
return {&m_result, size_type(result::difference_type(m_index) + o)};
|
|
}
|
|
|
|
inline const_result_iterator
|
|
operator+(result::difference_type o, const_result_iterator const &i)
|
|
{
|
|
return i + o;
|
|
}
|
|
|
|
inline const_result_iterator
|
|
const_result_iterator::operator-(result::difference_type o) const
|
|
{
|
|
return {&m_result, result_size_type(result::difference_type(m_index) - o)};
|
|
}
|
|
|
|
inline result::difference_type
|
|
const_result_iterator::operator-(const const_result_iterator &i) const
|
|
{
|
|
return result::difference_type(num() - i.num());
|
|
}
|
|
|
|
inline const_result_iterator result::end() const noexcept
|
|
{
|
|
return {this, size()};
|
|
}
|
|
|
|
|
|
inline const_result_iterator result::cend() const noexcept
|
|
{
|
|
return end();
|
|
}
|
|
|
|
|
|
inline const_reverse_result_iterator
|
|
operator+(result::difference_type n, const_reverse_result_iterator const &i)
|
|
{
|
|
return const_reverse_result_iterator{i.base() - n};
|
|
}
|
|
|
|
} // namespace pqxx
|
|
#endif
|