From 2b856f69d490f6cedffac03ecbed8fef318ecc43 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Feb 2013 15:50:06 +0200 Subject: Add support for change-tracking containers ODB now supports "smart" ordered containers. Such containers get extra functions for updating and deleting individual elements. Based on this functionality implement two change-tracking containers: odb::vector (equivalent to std::vector) and QOdbList (equivalent to QList). New tests: common/container/change-tracking and qt/common/container/change- tracking. --- odb/vector.hxx | 546 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 546 insertions(+) create mode 100644 odb/vector.hxx (limited to 'odb/vector.hxx') diff --git a/odb/vector.hxx b/odb/vector.hxx new file mode 100644 index 0000000..17f8653 --- /dev/null +++ b/odb/vector.hxx @@ -0,0 +1,546 @@ +// file : odb/vector.hxx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_VECTOR_HXX +#define ODB_VECTOR_HXX + +#include +#include // ODB_CXX11 + +#include +#include + +#ifdef ODB_CXX11 +# include // std::move, std::forward +# ifdef ODB_CXX11_INITIALIZER_LIST +# include +# endif +#endif + +#include + +namespace odb +{ + // An std::vector-like container that keeps track of changes. + // + // Note that the style and order of definitions is as appears + // in the standard. + // + template + class vector_iterator; + + template > + class vector: public vector_base + { + public: + typedef std::vector base_vector_type; + typedef typename base_vector_type::iterator base_iterator_type; + typedef typename base_vector_type::reverse_iterator + base_reverse_iterator_type; + // types: + // + typedef typename base_vector_type::reference reference; + typedef typename base_vector_type::const_reference const_reference; + typedef vector_iterator iterator; + typedef typename base_vector_type::const_iterator const_iterator; + typedef typename base_vector_type::size_type size_type; + typedef typename base_vector_type::difference_type difference_type; + typedef T value_type; + typedef A allocator_type; + typedef typename base_vector_type::pointer pointer; + typedef typename base_vector_type::const_pointer const_pointer; + typedef vector_iterator + reverse_iterator; + typedef typename base_vector_type::const_reverse_iterator + const_reverse_iterator; + // construct/copy/destroy: + // + explicit vector(const A& a = A()): v_ (a) {} + explicit vector(size_type n): v_ (n) {} // C++11 + vector(size_type n, const T& v, const A& a = A()): v_ (n, v, a) {} + template + vector(I f, I l, const A& a = A()) : v_ (f, l, a) {} + vector(const vector& x): vector_base (x), v_ (x.v_) {} + // ~vector() {} + vector& operator=(const vector&); + template + void assign(I f, I l); + void assign(size_type n, const T& u); + allocator_type get_allocator() const /*noexcept*/ + {return v_.get_allocator ();} + +#ifdef ODB_CXX11 + vector(vector&& x): vector_base (std::move (x)), v_ (std::move (x.v_)) {} + vector(const vector& x, const A& a): vector_base (x), v_ (x.v_, a) {} + vector(vector&& x, const A& a) + : vector_base (std::move (x)), v_ (std::move (x.v_), a) {} + vector& operator=(vector&&); +#ifdef ODB_CXX11_INITIALIZER_LIST + vector(std::initializer_list il, const A& a = A()): v_ (il, a) {} + vector& operator=(std::initializer_list); + void assign(std::initializer_list); +#endif +#endif + + // iterators: (all /*noexcept*/) + // + iterator begin() {return iterator (this, v_.begin ());} + const_iterator begin() const {return v_.begin ();} + iterator end() {return iterator (this, v_.end ());} + const_iterator end() const {return v_.end ();} + reverse_iterator rbegin() {return reverse_iterator (this, v_.rbegin ());} + const_reverse_iterator rbegin() const {return v_.rbegin ();} + reverse_iterator rend() {return reverse_iterator (this, v_.rend ());} + const_reverse_iterator rend() const {return v_.rend ();} + + // Return standard vector iterators. The begin() functions mark all + // the elements as modified. + // + base_iterator_type mbegin (); + base_iterator_type mend () {return v_.end ();} + base_reverse_iterator_type mrbegin (); + base_reverse_iterator_type mrend () {return v_.rend ();} + +#ifdef ODB_CXX11 + const_iterator cbegin() const {return v_.cbegin ();} + const_iterator cend() const {return v_.cend ();} + const_reverse_iterator crbegin() const {return v_.crbegin ();} + const_reverse_iterator crend() const {return v_.crend ();} +#endif + + // capacity: + // + size_type size() const /*noexcept*/ {return v_.size ();} + size_type max_size() const /*noexcept*/ {return v_.max_size ();} + void resize(size_type); // C++11 + void resize(size_type, const T&); + size_type capacity() const /*noexcept*/ {return v_.capacity ();} + bool empty() const /*noexcept*/ {return v_.empty ();} + void reserve(size_type); + +#ifdef ODB_CXX11 + void shrink_to_fit(); +#endif + + // element access: + // + //reference operator[](size_type n); + reference modify(size_type n); + const_reference operator[](size_type n) const {return v_[n];} + //reference at(size_type n); + reference modify_at(size_type n); + const_reference at(size_type n) const {return v_.at (n);} + //reference front(); + reference modify_front(); + const_reference front() const {return v_.front ();} + //reference back(); + reference modify_back(); + const_reference back() const {return v_.back ();} + + // data access: + // +#ifdef ODB_CXX11 + //T* data() noexcept; + T* modify_data() /*noexcept*/; + const T* data() const /*noexcept*/ {return v_.data ();} +#endif + + // modifiers: + // + void push_back(const T& x); + void pop_back(); + iterator insert(iterator position, const T& x); + void insert(iterator position, size_type n, const T& x); + template + void insert(iterator position, I first, I last); + iterator erase(iterator position); + iterator erase(iterator first, iterator last); + void swap(vector&); + void clear() /*noexcept*/; + +#ifdef ODB_CXX11 + // In C++11 all modifiers use const_iterator instead of iterator + // to represent position. However, some standard libraries (notably + // GCC's) still use iterator and so we will do that as well, for now. + // + void push_back(T&& x); + iterator insert(iterator position, T&& x); + +#ifdef ODB_CXX11_VARIADIC_TEMPLATE + template + void emplace_back(Args&&... args); + template + iterator emplace(iterator position, Args&&... args); +#endif +#endif + + // Interfacing with the base vector. + // + vector (const base_vector_type& x): v_ (x) {} + vector& operator= (const base_vector_type&); + operator const base_vector_type& () const {return v_;} + base_vector_type& base () {return v_;} + const base_vector_type& base () const {return v_;} + +#ifdef ODB_CXX11 + vector (base_vector_type&& x): v_ (std::move (x)) {} + vector& operator= (base_vector_type&&); +#endif + + // Change tracking (the rest comes from vector_base). + // + public: + void + _start () const {impl_.start (v_.size ());} + + private: + base_vector_type v_; + }; + + namespace core + { + using odb::vector; + } + + template + inline bool operator==(const vector& x, const vector& y) + {return x.base () == y.base ();} + + template + inline bool operator==(const vector& x, const std::vector& y) + {return x.base () == y;} + + template + inline bool operator==(const std::vector& x, const vector& y) + {return x == y.base ();} + + template + inline bool operator< (const vector& x, const vector& y) + {return x.base () < y.base ();} + + template + inline bool operator<(const vector& x, const std::vector& y) + {return x.base () < y;} + + template + inline bool operator<(const std::vector& x, const vector& y) + {return x < y.base ();} + + template + inline bool operator!=(const vector& x, const vector& y) + {return x.base () != y.base ();} + + template + inline bool operator!=(const vector& x, const std::vector& y) + {return x.base () != y;} + + template + inline bool operator!=(const std::vector& x, const vector& y) + {return x != y.base ();} + + template + inline bool operator> (const vector& x, const vector& y) + {return x.base () > y.base ();} + + template + inline bool operator>=(const vector& x, const vector& y) + {return x.base () >= y.base ();} + + template + inline bool operator>=(const vector& x, const std::vector& y) + {return x.base () >= y;} + + template + inline bool operator>=(const std::vector& x, const vector& y) + {return x >= y.base ();} + + template + inline bool operator<=(const vector& x, const vector& y) + {return x.base () <= y.base ();} + + template + inline bool operator<=(const vector& x, const std::vector& y) + {return x.base () <= y;} + + template + inline bool operator<=(const std::vector& x, const vector& y) + {return x <= y.base ();} + + template + class vector_iterator + { + public: + typedef V vector_type; + typedef I base_iterator_type; + typedef typename vector_type::const_iterator const_iterator_type; + typedef std::iterator_traits base_iterator_traits; + + typedef typename base_iterator_traits::value_type value_type; + typedef typename base_iterator_traits::difference_type difference_type; + typedef typename base_iterator_traits::pointer pointer; + typedef typename base_iterator_traits::reference reference; + typedef typename base_iterator_traits::iterator_category iterator_category; + + typedef typename vector_type::size_type size_type; + typedef typename vector_type::const_reference const_reference; + typedef typename vector_type::const_pointer const_pointer; + + vector_iterator (): v_ (0), i_ () {} + vector_iterator (vector_type* v, const base_iterator_type& i) + : v_ (v), i_ (i) {} + operator const_iterator_type () const {return i_;} + base_iterator_type base () const {return i_;} + vector_type* vector () const {return v_;} + + // Note: const_{reference,pointer}. + // + const_reference operator* () const {return *i_;} + const_pointer operator-> () const {return i_.operator -> ();} + const_reference operator[] (difference_type n) const {return i_[n];} + + // Modifiers. + // + reference modify () const; + reference modify (difference_type n) const; + + vector_iterator& operator++ () {++i_; return *this;} + vector_iterator operator++ (int) {return vector_iterator (v_, i_++);} + vector_iterator& operator-- () {--i_; return *this;} + vector_iterator operator-- (int) {return vector_iterator (v_, i_--);} + + vector_iterator operator+ (difference_type n) const + {return vector_iterator (v_, i_ + n);} + vector_iterator& operator+= (difference_type n) {i_ += n; return *this;} + vector_iterator operator- (difference_type n) const + {return vector_iterator (v_, i_ - n);} + vector_iterator& operator-= (difference_type n) {i_ -= n; return *this;} + + // Implementation details. + // + public: + base_iterator_type _base () const {return i_;} // Same as base (). + + private: + vector_type* v_; + base_iterator_type i_; + }; + + template + class vector_iterator > + { + public: + typedef V vector_type; + typedef std::reverse_iterator base_iterator_type; + typedef typename vector_type::const_reverse_iterator const_iterator_type; + typedef std::iterator_traits base_iterator_traits; + + typedef typename vector_type::iterator iterator_type; + typedef typename base_iterator_traits::value_type value_type; + typedef typename base_iterator_traits::difference_type difference_type; + typedef typename base_iterator_traits::pointer pointer; + typedef typename base_iterator_traits::reference reference; + typedef typename base_iterator_traits::iterator_category iterator_category; + + typedef typename vector_type::size_type size_type; + typedef typename vector_type::const_reference const_reference; + typedef typename vector_type::const_pointer const_pointer; + + vector_iterator (): v_ (0), i_ () {} + explicit vector_iterator (const iterator_type& i) + : v_ (i.vector ()), i_ (i.base ()) {} + vector_iterator (vector_type* v, const base_iterator_type& i) + : v_ (v), i_ (i) {} + operator const_iterator_type () const {return i_;} + iterator_type base () const {return iterator_type (v_, i_.base ());} + base_iterator_type rbase () const {return i_;} + vector_type* vector () const {return v_;} + + // Note: const_{reference,pointer}. + // + const_reference operator* () const {return *i_;} + const_pointer operator-> () const {return i_.operator -> ();} + const_reference operator[] (difference_type n) const {return i_[n];} + + // Modifiers. + // + reference modify () const; + reference modify (difference_type n) const; + + vector_iterator& operator++ () {++i_; return *this;} + vector_iterator operator++ (int) {return vector_iterator (v_, i_++);} + vector_iterator& operator-- () {--i_; return *this;} + vector_iterator operator-- (int) {return vector_iterator (v_, i_--);} + + vector_iterator operator+ (difference_type n) const + {return vector_iterator (v_, i_ + n);} + vector_iterator& operator+= (difference_type n) {i_ += n; return *this;} + vector_iterator operator- (difference_type n) const + {return vector_iterator (v_, i_ - n);} + vector_iterator& operator-= (difference_type n) {i_ -= n; return *this;} + + // Implementation details. + // + public: + base_iterator_type _base () const {return i_;} // Same as rbase(). + + private: + vector_type* v_; + base_iterator_type i_; + }; + + // operator== + // + template + inline bool + operator== (const vector_iterator& x, const vector_iterator& y) + {return x._base () == y._base ();} + + template + inline bool + operator== (const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () == y;} + + template + inline bool + operator== (const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x == y._base ();} + + // operator< + // + template + inline bool + operator< (const vector_iterator& x, const vector_iterator& y) + {return x._base () < y._base ();} + + template + inline bool + operator< (const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () < y;} + + template + inline bool + operator< (const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x < y._base ();} + + // operator!= + // + template + inline bool + operator!= (const vector_iterator& x, const vector_iterator& y) + {return x._base () != y._base ();} + + template + inline bool + operator!= (const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () != y;} + + template + inline bool + operator!= (const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x != y._base ();} + + // operator> + // + template + inline bool + operator> (const vector_iterator& x, const vector_iterator& y) + {return x._base () > y._base ();} + + template + inline bool + operator> (const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () > y;} + + template + inline bool + operator> (const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x > y._base ();} + + // operator>= + // + template + inline bool + operator>= (const vector_iterator& x, const vector_iterator& y) + {return x._base () >= y._base ();} + + template + inline bool + operator>= (const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () >= y;} + + template + inline bool + operator>= (const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x >= y._base ();} + + // operator<= + // + template + inline bool + operator<= (const vector_iterator& x, const vector_iterator& y) + {return x._base () <= y._base ();} + + template + inline bool + operator<= (const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () <= y;} + + template + inline bool + operator<= (const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x <= y._base ();} + + // operator- + // + template + inline typename vector_iterator::difference_type + operator-(const vector_iterator& x, const vector_iterator& y) + {return x._base () - y._base ();} + + template + inline typename vector_iterator::difference_type + operator-(const vector_iterator& x, + const typename vector_iterator::const_iterator_type& y) + {return x._base () - y;} + + template + inline typename vector_iterator::difference_type + operator-(const typename vector_iterator::const_iterator_type& x, + const vector_iterator& y) + {return x - y._base ();} + + // operator+ + // + template + inline vector_iterator + operator+(typename vector_iterator::difference_type n, + const vector_iterator& x) + {return vector_iterator (x.vector (), n + x._base ());} +} + +namespace std +{ + template + inline void swap(odb::vector& x, odb::vector& y) {x.swap (y);} +} + +#include + +#include + +#include + +#endif // ODB_VECTOR_HXX -- cgit v1.1