|
- #pragma once
-
- #include "row.h"
-
- #include "field.inl"
- #include "result.inl"
-
- namespace cppmariadb
- {
-
- namespace __impl
- {
-
- template<typename T>
- struct row_iterator
- {
- public:
- using this_type = row_iterator<T>;
- using iterator_category = std::random_access_iterator_tag;
- using value_type = T;
- using difference_type = ssize_t;
- using pointer = T*;
- using reference = T&;
-
- private:
- enum class compare_result : int
- {
- lower = -1,
- equals = 0,
- greater = 1,
- mismatch = 2
- };
-
- using value_ptru_type = std::unique_ptr<value_type>;
-
- private:
- const row* _owner;
- ssize_t _index;
- ssize_t _direction;
- mutable value_ptru_type _cache;
-
- public:
- inline row_iterator(const row& p_row, ssize_t index, ssize_t direction)
- : _owner (&p_row)
- , _index (index)
- , _direction(direction)
- { }
-
- inline row_iterator(const this_type& other)
- { assign(other); }
-
- public:
- inline bool operator == (const this_type& other) const
- { return compare(other) == compare_result::equals; }
-
- inline bool operator != (const this_type& other) const
- { return compare(other) != compare_result::equals; }
-
- inline bool operator < (const this_type& other) const
- { return compare(other) == compare_result::less; }
-
- inline bool operator <= (const this_type& other) const
- {
- auto c = compare(other);
- return (c == compare_result::less || c == compare_result::equals);
- }
-
- inline bool operator > (const this_type& other) const
- { return compare(other) == compare_result::greater; }
-
- inline bool operator >= (const this_type& other) const
- {
- auto c = compare(other);
- return (c == compare_result::greater || c == compare_result::equals);
- }
-
- inline reference operator * () const
- { return field(); }
-
- inline pointer operator -> () const
- { return &field(); }
-
- inline this_type& operator ++ ()
- {
- next();
- return *this;
- }
-
- inline this_type& operator -- ()
- {
- prev();
- return *this;
- }
-
- inline this_type operator ++ (int)
- {
- auto tmp(*this);
- next();
- return tmp;
- }
-
- inline this_type operator -- (int)
- {
- auto tmp(*this);
- prev();
- return tmp;
- }
-
- inline this_type& operator += (difference_type diff)
- {
- next(diff);
- return *this;
- }
-
- inline this_type& operator -= (difference_type diff)
- {
- prev(diff);
- return *this;
- }
-
- inline this_type operator + (difference_type diff) const
- {
- auto tmp(*this);
- tmp += diff;
- return tmp;
- }
-
- inline this_type operator - (difference_type diff) const
- {
- auto tmp(*this);
- tmp -= diff;
- return tmp;
- }
-
- inline difference_type operator - (const this_type& other) const
- { return (_index - other._index) * _direction; }
-
- inline this_type operator [] (difference_type diff)
- {
- auto tmp(*this);
- tmp += diff;
- return tmp;
- }
-
- private:
- inline compare_result compare(const this_type& other) const
- {
- if (_owner != other._owner)
- return compare_result::mismatch;
- else if (_index < other._index)
- return compare_result::lower;
- else if (_index > other._index)
- return compare_result::greater;
- else
- return compare_result::equals;
- }
-
- inline reference field() const
- {
- if (!_cache)
- _cache.reset(new value_type(_owner->at(_index)));
- return *_cache;
- }
-
- inline void assign(const this_type& other)
- {
- _owner = other._owner;
- _index = other._index;
- _direction = other._direction;
- _cache.reset();
- }
-
- inline void next(difference_type i = 1)
- {
- _cache.reset();
- _index = _index + _direction * i;
- }
-
- inline void prev(difference_type i = 1)
- {
- _cache.reset();
- _index = _index - _direction * i;
- }
- };
-
- }
-
- /* row */
-
- row::row(const result& p_result, MYSQL_ROW p_row)
- : handle(p_row)
- , _result (p_result)
- , _lengths (nullptr)
- { }
-
- field row::operator[](size_t i) const
- { return at(i); }
-
- field row::operator[](const std::string& name) const
- { return at(name); }
-
- const column_vector& row::columns() const
- { return _result.columns(); }
-
- unsigned int row::size() const
- { return _result.columncount(); }
-
- row::iterator_type row::begin() const
- { return iterator_type(*this, 0, 1); }
-
- row::iterator_type row::end() const
- { return iterator_type(*this, size(), 1); }
-
- row::const_iterator_type row::cbegin() const
- { return const_iterator_type(*this, 0, 1); }
-
- row::const_iterator_type row::cend() const
- { return const_iterator_type(*this, size(), 1); }
-
- row::iterator_type row::rbegin() const
- { return iterator_type(*this, size()-1, -1); }
-
- row::iterator_type row::rend() const
- { return iterator_type(*this, -1, -1); }
-
- row::const_iterator_type row::crbegin() const
- { return const_iterator_type(*this, size()-1, -1); }
-
- row::const_iterator_type row::crend() const
- { return const_iterator_type(*this, -1, -1); }
-
- }
|