From e93dcc2ecabee46d31aedf9f4ddc8058956c78ad Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Feb 2013 15:50:07 +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/qt/containers/list-iterator.hxx | 31 ++ odb/qt/containers/list-traits.hxx | 105 +++++++ odb/qt/containers/list-traits.txx | 73 +++++ odb/qt/containers/list.hxx | 422 ++++++++++++++++++++++++++++ odb/qt/containers/list.ixx | 317 +++++++++++++++++++++ odb/qt/containers/mutable-list-iterator.hxx | 111 ++++++++ odb/qt/containers/qhash-traits.hxx | 26 +- odb/qt/containers/qlinked-list-traits.hxx | 13 +- odb/qt/containers/qlist-traits.hxx | 11 +- odb/qt/containers/qmap-traits.hxx | 22 +- odb/qt/containers/qset-traits.hxx | 11 +- odb/qt/containers/qvector-traits.hxx | 11 +- odb/qt/list-iterator.hxx | 10 + odb/qt/list.hxx | 10 + odb/qt/mutable-list-iterator.hxx | 10 + 15 files changed, 1140 insertions(+), 43 deletions(-) create mode 100644 odb/qt/containers/list-iterator.hxx create mode 100644 odb/qt/containers/list-traits.hxx create mode 100644 odb/qt/containers/list-traits.txx create mode 100644 odb/qt/containers/list.hxx create mode 100644 odb/qt/containers/list.ixx create mode 100644 odb/qt/containers/mutable-list-iterator.hxx create mode 100644 odb/qt/list-iterator.hxx create mode 100644 odb/qt/list.hxx create mode 100644 odb/qt/mutable-list-iterator.hxx diff --git a/odb/qt/containers/list-iterator.hxx b/odb/qt/containers/list-iterator.hxx new file mode 100644 index 0000000..d75491a --- /dev/null +++ b/odb/qt/containers/list-iterator.hxx @@ -0,0 +1,31 @@ +// file : odb/qt/containers/list-iterator.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_LIST_ITERATOR_HXX +#define ODB_QT_CONTAINERS_LIST_ITERATOR_HXX + +#include + +#include + +#include + +// Java-style QListIterator-like iterator. You can also use the +// QListIterator directly (but not QMutableListIterator). +// +template +class QOdbListIterator: public QListIterator +{ +public: + QOdbListIterator (const QOdbList& c): QListIterator (c) {} + QOdbListIterator& operator=(const QOdbList& c) + { + static_cast&> (*this) = c; + return *this; + } +}; + +#include + +#endif // ODB_QT_CONTAINERS_LIST_ITERATOR_HXX diff --git a/odb/qt/containers/list-traits.hxx b/odb/qt/containers/list-traits.hxx new file mode 100644 index 0000000..c9c3deb --- /dev/null +++ b/odb/qt/containers/list-traits.hxx @@ -0,0 +1,105 @@ +// file : odb/qt/containers/list-traits.hxx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_LIST_TRAITS_HXX +#define ODB_QT_CONTAINERS_LIST_TRAITS_HXX + +#include + +#include +#include +#include + +#include + +namespace odb +{ + template + class access::container_traits > + { + public: + static const container_kind kind = ck_ordered; + static const bool smart = true; + + typedef QOdbList container_type; + + typedef V value_type; + typedef typename container_type::size_type index_type; + + typedef smart_ordered_functions functions; + typedef ordered_functions dumb_functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + + // Now that this container is persistent, start tracking changes. + // + c._start (); + } + + static void + load (container_type& c, bool more, const functions& f) + { + // Stop tracking changes. + // + c._stop (); + + // Load. + // + c.clear (); + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.modify_back ()); + } + + // Start tracking changes. + // + c._start (); + } + + static void + update (const container_type&, const functions&); + + static void + erase (const container_type* c, const functions& f) + { + f.delete_ (0); + + // Stop tracking changes. + // + if (c != 0) + c->_stop (); + } + + // Version of load() for dumb functions. Used to support + // inverse members of the container type. The implementation + // is identical to the smart one except we don't turn off/on + // change tracking. + // + static void + load (container_type& c, bool more, const dumb_functions& f) + { + c.clear (); + + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.modify_back ()); + } + } + }; +} + +#include + +#include + +#endif // ODB_QT_CONTAINERS_LIST_TRAITS_HXX diff --git a/odb/qt/containers/list-traits.txx b/odb/qt/containers/list-traits.txx new file mode 100644 index 0000000..48cf28e --- /dev/null +++ b/odb/qt/containers/list-traits.txx @@ -0,0 +1,73 @@ +// file : odb/qt/containers/list-traits.txx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + template + void access::container_traits >:: + update (const container_type& c, const functions& f) + { + bool u (false); // Updated flag. + + if (c._tracking ()) + { + const vector_impl& impl (c._impl ()); + + for (std::size_t i (0), n (impl.size ()); i < n; ++i) + { + vector_impl::element_state_type s (impl.state (i)); + + switch (s) + { + case vector_impl::state_unchanged: + { + break; + } + case vector_impl::state_inserted: + { + f.insert (i, c[static_cast (i)]); + u = u || true; + break; + } + case vector_impl::state_updated: + { + f.update (i, c[static_cast (i)]); + u = u || true; + break; + } + case vector_impl::state_erased: + { + f.delete_ (i); // Delete from i onwards. + u = u || true; + break; + } + } + + // We delete all trailing elements in one go. + // + if (s == vector_impl::state_erased) + break; + } + } + else + { + // Fall back to delete all/insert all. + // + f.delete_ (0); + + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + + u = true; + } + + // Arm the rollback callback and (re)start change tracking. + // + if (u) + { + c._arm (transaction::current ()); + c._start (); + } + } +} diff --git a/odb/qt/containers/list.hxx b/odb/qt/containers/list.hxx new file mode 100644 index 0000000..c55dd44 --- /dev/null +++ b/odb/qt/containers/list.hxx @@ -0,0 +1,422 @@ +// file : odb/qt/containers/list.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_LIST_HXX +#define ODB_QT_CONTAINERS_LIST_HXX + +#include +#include // ODB_CXX11 + +#include + +#ifdef ODB_CXX11 +# include // std::move +# ifdef ODB_CXX11_INITIALIZER_LIST +# include +# endif +#endif + +#include + +// A QList-like container that keeps track of changes. +// +// Note that the style and order of definitions is (mostly) as +// appears in the qlist.h Qt header (except for some cleanups, +// such as superfluous inline use). +// +template +class QOdbListIteratorImpl; + +template +class QOdbList: public odb::vector_base +{ +public: + typedef QList base_list_type; + typedef typename base_list_type::iterator base_iterator_type; + + QOdbList() {} + QOdbList(const QOdbList &x): vector_base (x), l_ (x.l_) {} + // ~QOdbList(); + QOdbList &operator=(const QOdbList &l); + void swap(QOdbList &other); + +#ifdef ODB_CXX11 + QOdbList(QOdbList &&x): vector_base (std::move (x)), l_ (std::move (x.l_)) {} + QOdbList &operator=(QOdbList &&other); +#ifdef ODB_CXX11_INITIALIZER_LIST + QOdbList(std::initializer_list il): l_ (il) {} +#endif +#endif + + // Implicit conversion. + // + bool operator==(const QList &x) const {return l_ == x;} + bool operator!=(const QList &x) const {return l_ != x;} + + int size() const {return l_.size ();} + void detach() {l_.detach ();} + void detachShared() {l_.detachShared ();} + bool isDetached() const {return l_.isDetached ();} + void setSharable(bool sharable) {l_.setSharable (sharable);} + // Implicit conversion. + bool isSharedWith(const QList &x) const {return l_.isSharedWith (x);} + bool isEmpty() const {return l_.isEmpty ();} + void clear(); + + const T &at(int i) const {return l_.at (i);} + const T &operator[](int i) const {return l_[i];} + //T &operator[](int i); + T &modify (int i); + + void reserve(int size); + void append(const T &t); + void append(const QList &t); // Implicit conversion. + void prepend(const T &t); + void insert(int i, const T &t); + void replace(int i, const T &t); + void removeAt(int i); + int removeAll(const T &t); + bool removeOne(const T &t); + T takeAt(int i); + T takeFirst(); + T takeLast(); + void move(int from, int to); + void swap(int i, int j); + + int indexOf(const T &t, int from = 0) const {return l_.indexOf (t, from);} + int lastIndexOf(const T &t, int from = -1) const + {return l_.lastIndexOf (t, from);} + bool contains(const T &t) const {return l_.contains (t);} + int count(const T &t) const {return l_.count (t);} + + typedef QOdbListIteratorImpl iterator; + typedef typename base_list_type::const_iterator const_iterator; + + // stl style + iterator begin() {return iterator (this, l_.begin ());} + const_iterator begin() const {return l_.begin ();} + const_iterator cbegin() const {return l_.cbegin ();} + const_iterator constBegin() const {return l_.constBegin ();} + iterator end() {return iterator (this, l_.end ());} + const_iterator end() const {return l_.end ();} + const_iterator cend() const {return l_.cend ();} + const_iterator constEnd() const {return l_.constEnd ();} + + // Return QList iterators. The begin() functions mark all + // the elements as modified. + // + base_iterator_type mbegin (); + base_iterator_type modifybegin () {return mbegin ();} + base_iterator_type mend () {return l_.end ();} + base_iterator_type modifyEnd () {return mend ();} + + iterator insert(iterator before, const T &t); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + + // more Qt + typedef iterator Iterator; + typedef const_iterator ConstIterator; + + int count() const {return l_.count ();} + int length() const {return l_.length ();} + //T& first(); + T& modify_first(); + const T& first() const {return l_.first ();} + //T& last(); + T& modify_last(); + const T& last() const {return l_.last ();} + void removeFirst(); + void removeLast(); + bool startsWith(const T &t) const {return l_.startsWith (t);} + bool endsWith(const T &t) const {return l_.endsWith (t);} + QList mid(int pos, int length = -1) const {return l_.mid (pos, length);} + + T value(int i) const {return l_.value (i);} + T value(int i, const T &defValue) const {return l_.value (i, defValue);} + + // stl compatibility + void push_back(const T &t) {append(t);} + void push_front(const T &t) {prepend(t);} + //T& front(); + T& modify_front() {return modify_first ();} + const T& front() const {return l_.front ();} + //T& back(); + T& modify_back() {return modify_last ();} + const T& back() const {return l_.back ();} + void pop_front() {removeFirst();} + void pop_back() {removeLast();} + bool empty() const {return l_.empty ();} + + typedef int size_type; + typedef T value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef typename base_list_type::difference_type difference_type; + + // comfort + // Implicit conversion. + QOdbList &operator+=(const QList &l) {append (l); return *this;} + QOdbList operator+(const QList &l) const + {QOdbList r (*this); r.append (l); return r;} + QOdbList &operator+=(const T &t) {append (t); return *this;} + QOdbList &operator<< (const T &t) {append (t); return *this;} + QOdbList &operator<<(const QList &l) {append (l); return *this;} + + QVector toVector() const {return l_.toVector ();} + QSet toSet() const {return l_.toSet ();} + + static QOdbList fromVector(const QVector &v) + {return base_list_type::fromVector (v);} + static QOdbList fromSet(const QSet &s) + {return base_list_type::fromSet (s);} + + static QOdbList fromStdList(const std::list &l) + {return base_list_type::fromStdList (l);} + std::list toStdList() const {return l_.toStdList ();} + + // Interfacing with the base list. + // + QOdbList (const base_list_type& x): l_ (x) {} + QOdbList& operator= (const base_list_type&); + operator const base_list_type& () const {return l_;} + base_list_type& base () {return l_;} + const base_list_type& base () const {return l_;} + +#ifdef ODB_CXX11 + QOdbList (base_list_type&& x): l_ (std::move (x)) {} + QOdbList& operator= (base_list_type&&); +#endif + + // Change tracking (the rest comes from vector_base). + // +public: + void _start () const {impl_.start (l_.size ());} + +private: + base_list_type l_; +}; + +template +class QOdbListIteratorImpl +{ +public: + typedef L list_type; + typedef typename list_type::base_iterator_type base_iterator_type; + typedef typename list_type::const_iterator const_iterator_type; + + typedef typename base_iterator_type::iterator_category iterator_category; + typedef typename base_iterator_type::difference_type difference_type; + typedef typename base_iterator_type::value_type value_type; + typedef typename base_iterator_type::pointer pointer; + typedef typename base_iterator_type::reference reference; + + typedef typename list_type::size_type size_type; + typedef typename list_type::const_reference const_reference; + typedef typename list_type::const_pointer const_pointer; + + QOdbListIteratorImpl (): l_ (0), i_ () {} + QOdbListIteratorImpl (list_type* l, const base_iterator_type& i) + : l_ (l), i_ (i) {} + +#ifndef QT_STRICT_ITERATORS + operator const_iterator_type () const {return i_;} +#endif + base_iterator_type base () const {return i_;} + list_type* list () const {return l_;} + + // 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; + + QOdbListIteratorImpl& operator++ () {++i_; return *this;} + QOdbListIteratorImpl operator++ (int) + {return QOdbListIteratorImpl (l_, i_++);} + QOdbListIteratorImpl& operator-- () {--i_; return *this;} + QOdbListIteratorImpl operator-- (int) + {return QOdbListIteratorImpl (l_, i_--);} + + QOdbListIteratorImpl operator+ (int n) const + {return QOdbListIteratorImpl (l_, i_ + n);} + QOdbListIteratorImpl& operator+= (int n) {i_ += n; return *this;} + QOdbListIteratorImpl operator- (int n) const + {return QOdbListIteratorImpl (l_, i_ - n);} + QOdbListIteratorImpl& operator-= (int n) {i_ -= n; return *this;} + +private: + list_type* l_; + base_iterator_type i_; +}; + +// operator== +// +template +inline bool +operator== (const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () == y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline bool +operator== (const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () == y;} + +template +inline bool +operator== (const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x == y.base ();} +#endif + +// operator< +// +template +inline bool +operator< (const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () < y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline bool +operator< (const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () < y;} + +template +inline bool +operator< (const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x < y.base ();} +#endif + +// operator!= +// +template +inline bool +operator!= (const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () != y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline bool +operator!= (const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () != y;} + +template +inline bool +operator!= (const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x != y.base ();} +#endif + +// operator> +// +template +inline bool +operator> (const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () > y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline bool +operator> (const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () > y;} + +template +inline bool +operator> (const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x > y.base ();} +#endif + +// operator>= +// +template +inline bool +operator>= (const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () >= y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline bool +operator>= (const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () >= y;} + +template +inline bool +operator>= (const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x >= y.base ();} +#endif + +// operator<= +// +template +inline bool +operator<= (const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () <= y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline bool +operator<= (const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () <= y;} + +template +inline bool +operator<= (const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x <= y.base ();} +#endif + +// operator- +// +template +inline typename QOdbListIteratorImpl::difference_type +operator-(const QOdbListIteratorImpl& x, const QOdbListIteratorImpl& y) +{return x.base () - y.base ();} + +#ifndef QT_STRICT_ITERATORS +template +inline typename QOdbListIteratorImpl::difference_type +operator-(const QOdbListIteratorImpl& x, + const typename QOdbListIteratorImpl::const_iterator_type& y) +{return x.base () - y;} + +template +inline typename QOdbListIteratorImpl::difference_type +operator-(const typename QOdbListIteratorImpl::const_iterator_type& x, + const QOdbListIteratorImpl& y) +{return x - y.base ();} +#endif + +// operator+ +// +template +inline QOdbListIteratorImpl +operator+(typename QOdbListIteratorImpl::difference_type n, + const QOdbListIteratorImpl& x) +{return QOdbListIteratorImpl (x.list (), n + x.base ());} + +#include + +#include + +#include + +#endif // ODB_QT_CONTAINERS_LIST_HXX diff --git a/odb/qt/containers/list.ixx b/odb/qt/containers/list.ixx new file mode 100644 index 0000000..90a10e6 --- /dev/null +++ b/odb/qt/containers/list.ixx @@ -0,0 +1,317 @@ +// file : odb/qt/containers/list.ixx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +// +// QOdbList +// + +template +inline QOdbList& QOdbList:: +operator= (const QOdbList& x) +{ + l_ = x.l_; + if (_tracking ()) + impl_.assign (static_cast (l_.size ())); + return *this; +} + +template +inline QOdbList& QOdbList:: +operator= (const base_list_type& x) +{ + l_ = x; + if (_tracking ()) + impl_.assign (static_cast (l_.size ())); + return *this; +} + +#ifdef ODB_CXX11 +template +inline QOdbList& QOdbList:: +operator= (QOdbList&& x) +{ + l_ = std::move (x.l_); + if (_tracking ()) + impl_.assign (static_cast (l_.size ())); + return *this; +} + +template +inline QOdbList& QOdbList:: +operator= (base_list_type&& x) +{ + l_ = std::move (x); + if (_tracking ()) + impl_.assign (static_cast (l_.size ())); + return *this; +} +#endif + +template +inline void QOdbList:: +swap (QOdbList& x) +{ + l_.swap (x.l_); + vector_base::swap (x); +} + +template +inline void QOdbList:: +clear() +{ + l_.clear (); + if (_tracking ()) + impl_.clear (); +} + +template +inline T& QOdbList:: +modify (int i) +{ + T& r (l_[i]); + if (_tracking ()) + impl_.modify (static_cast (i)); + return r; +} + +template +inline void QOdbList:: +reserve (int n) +{ + l_.reserve (n); + if (_tracking ()) + impl_.reserve (static_cast (n)); +} + +template +inline void QOdbList:: +append (const T& x) +{ + l_.append (x); + if (_tracking ()) + impl_.push_back (); +} + +template +inline void QOdbList:: +append (const QList& x) +{ + l_.append (x); + if (_tracking ()) + impl_.push_back (static_cast (x.size ())); +} + +template +inline void QOdbList:: +prepend (const T& x) +{ + l_.prepend (x); + if (_tracking ()) + impl_.insert (0); +} + +template +inline void QOdbList:: +insert (int i, const T& x) +{ + l_.insert (i, x); + if (_tracking ()) + impl_.insert (static_cast (i)); +} + +template +inline void QOdbList:: +replace (int i, const T& x) +{ + l_.insert (i, x); + if (_tracking ()) + impl_.modify (static_cast (i)); +} + +template +inline void QOdbList:: +removeAt (int i) +{ + l_.removeAt (i); + if (_tracking ()) + impl_.erase (static_cast (i)); +} + +template +inline int QOdbList:: +removeAll (const T& x) +{ + // We have to re-implement this one ourselves since we need to + // know the indexes of the removed elements. + // + int r (0); + for (int i (l_.indexOf (x)); i != -1; i = l_.indexOf (x, i)) + { + removeAt (i); + r++; + } + return r; +} + +template +inline bool QOdbList:: +removeOne (const T& x) +{ + // We have to re-implement this one ourselves since we need to + // know the index of the removed element. + // + int i (l_.indexOf (x)); + if (i != -1) + removeAt (i); + return i != -1; +} + +template +inline T QOdbList:: +takeAt (int i) +{ + if (_tracking ()) + impl_.erase (static_cast (i)); + return l_.takeAt (i); +} + +template +inline T QOdbList:: +takeFirst () +{ + if (_tracking ()) + impl_.erase (0); + return l_.takeFirst (); +} + +template +inline T QOdbList:: +takeLast () +{ + if (_tracking ()) + impl_.pop_back (); + return l_.takeLast (); +} + +template +inline void QOdbList:: +move (int from, int to) +{ + l_.move (from, to); + if (_tracking ()) + { + impl_.erase (static_cast (from)); + impl_.insert (static_cast (to)); + } +} + +template +inline void QOdbList:: +swap (int i, int j) +{ + l_.swap (i, j); + if (_tracking ()) + { + impl_.modify (static_cast (i)); + impl_.modify (static_cast (j)); + } +} + +template +inline typename QOdbList::base_iterator_type QOdbList:: +mbegin () +{ + if (_tracking ()) + impl_.modify (0, static_cast (l_.size ())); + return l_.begin (); +} + +template +inline typename QOdbList::iterator QOdbList:: +insert (iterator p, const T& x) +{ + if (_tracking ()) + impl_.insert (static_cast (p.base () - l_.begin ())); + return iterator (this, l_.insert (p.base (), x)); +} + +template +inline typename QOdbList::iterator QOdbList:: +erase (iterator p) +{ + if (_tracking ()) + impl_.erase (static_cast (p.base () - l_.begin ())); + return iterator (this, l_.erase (p.base ())); +} + +template +inline typename QOdbList::iterator QOdbList:: +erase (iterator f, iterator l) +{ + if (_tracking ()) + impl_.erase (static_cast (f.base () - l_.begin ()), + static_cast (l - f)); + return iterator (this, l_.erase (f.base (), l.base ())); +} + +template +inline T& QOdbList:: +modify_first () +{ + T& r (l_.first ()); + if (_tracking ()) + impl_.modify (0); + return r; +} + +template +inline T& QOdbList:: +modify_last () +{ + T& r (l_.last ()); + if (_tracking ()) + impl_.modify (static_cast (l_.size () - 1)); + return r; +} + +template +inline void QOdbList:: +removeFirst () +{ + l_.removeFirst (); + if (_tracking ()) + impl_.erase (0); +} + +template +inline void QOdbList:: +removeLast () +{ + l_.removeLast (); + if (_tracking ()) + impl_.pop_back (); +} + +// +// QOdbListIteratorImpl +// + +template +inline typename QOdbListIteratorImpl::reference QOdbListIteratorImpl:: +modify () const +{ + if (l_->_tracking ()) + l_->_impl ().modify (static_cast (i_ - l_->base ().begin ())); + return *i_; +} + +template +inline typename QOdbListIteratorImpl::reference QOdbListIteratorImpl:: +modify (difference_type n) const +{ + if (l_->_tracking ()) + l_->_impl ().modify ( + static_cast (i_ - l_->base ().begin () + n)); + return i_[n]; +} diff --git a/odb/qt/containers/mutable-list-iterator.hxx b/odb/qt/containers/mutable-list-iterator.hxx new file mode 100644 index 0000000..ff9d9f5 --- /dev/null +++ b/odb/qt/containers/mutable-list-iterator.hxx @@ -0,0 +1,111 @@ +// file : odb/qt/containers/mutable-list-iterator.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_MUTABLE_LIST_ITERATOR_HXX +#define ODB_QT_CONTAINERS_MUTABLE_LIST_ITERATOR_HXX + +#include + +#include + +#include + +// Java-style QMutableListIterator-like iterator. The implementation +// is based on what's found in qiterator.h. +// +template +class QMutableOdbListIterator +{ +public: + QMutableOdbListIterator(QOdbList &x) + : c (&x) + { + c->setSharable(false); + i = c->begin(); + n = c->end(); + } + + ~QMutableOdbListIterator() {c->setSharable(true);} + + QMutableOdbListIterator &operator=(QOdbList &x) + { + c->setSharable(true); + c = &x; + c->setSharable(false); + i = c->begin(); + n = c->end(); + return *this; + } + + void toFront() {i = c->begin(); n = c->end();} + void toBack() {i = c->end(); n = i;} + bool hasNext() const {return c->constEnd() != const_iterator(i.base ());} + bool hasPrevious() const + { + return c->constBegin() != const_iterator(i.base ()); + } + + bool findNext(const T &t) + { + while (c->constEnd() != const_iterator((n = i).base ())) + if (*i++ == t) + return true; + return false; + } + + bool findPrevious(const T &t) + { + while (c->constBegin() != const_iterator(i.base ())) + if (*(n = --i) == t) + return true; + + n = c->end(); + return false; + } + + T &next() {n = i++; return n.modify ();} + T &peekNext() const {return i.modify ();} + T &previous() {n = --i; return n.modify ();} + T &peekPrevious() const {iterator p (i); return (--p).modify ();} + + void remove() + { + if (c->constEnd() != const_iterator(n.base ())) + { + i = c->erase (n); + n = c->end(); + } + } + + void setValue(const T &t) const + { + if (c->constEnd() != const_iterator(n.base ())) + n.modify () = t; + } + + T &value() + { + Q_ASSERT(c->constEnd() != const_iterator(n.base ())); + return n.modify (); + } + + const T &value() const + { + Q_ASSERT(c->constEnd() != const_iterator(n.base ())); + return *n; + } + + void insert(const T &t) {n = i = c->insert(i, t); ++i;} + +private: + typedef typename QOdbList::iterator iterator; + typedef typename QOdbList::const_iterator const_iterator; + + QOdbList* c; + iterator i, n; +}; + +#include + +#endif // ODB_QT_CONTAINERS_MUTABLE_LIST_ITERATOR_HXX diff --git a/odb/qt/containers/qhash-traits.hxx b/odb/qt/containers/qhash-traits.hxx index 57b072e..b44bc51 100644 --- a/odb/qt/containers/qhash-traits.hxx +++ b/odb/qt/containers/qhash-traits.hxx @@ -18,7 +18,8 @@ namespace odb class access::container_traits > { public: - static container_kind const kind = ck_map; + static const container_kind kind = ck_map; + static const bool smart = false; typedef QHash container_type; typedef Key key_type; @@ -32,7 +33,7 @@ namespace odb { for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void @@ -44,7 +45,7 @@ namespace odb { key_type k; value_type v; - more = f.load_all (k, v); + more = f.select (k, v); c.insert (k, v); // @@ Use std::move in C++11. } } @@ -52,17 +53,17 @@ namespace odb static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; @@ -74,7 +75,8 @@ namespace odb class access::container_traits > { public: - static container_kind const kind = ck_multimap; + static const container_kind kind = ck_multimap; + static const bool smart = false; typedef QMultiHash container_type; typedef Key key_type; @@ -88,7 +90,7 @@ namespace odb { for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void @@ -100,7 +102,7 @@ namespace odb { key_type k; value_type v; - more = f.load_all (k, v); + more = f.select (k, v); c.insert (k, v); //@@ Use std::move in C++11. } } @@ -108,17 +110,17 @@ namespace odb static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; } diff --git a/odb/qt/containers/qlinked-list-traits.hxx b/odb/qt/containers/qlinked-list-traits.hxx index 6c1e9f0..c995fe1 100644 --- a/odb/qt/containers/qlinked-list-traits.hxx +++ b/odb/qt/containers/qlinked-list-traits.hxx @@ -17,7 +17,8 @@ namespace odb class access::container_traits > { public: - static container_kind const kind = ck_ordered; + static const container_kind kind = ck_ordered; + static const bool smart = false; typedef QLinkedList container_type; @@ -33,7 +34,7 @@ namespace odb index_type i (0); for (typename container_type::const_iterator j (c.begin ()), e (c.end ()); j != e; ++j) - f.insert_one (i++, *j); + f.insert (i++, *j); } static void @@ -45,25 +46,25 @@ namespace odb { index_type dummy; c.append (value_type ()); - more = f.load_all (dummy, c.back ()); + more = f.select (dummy, c.back ()); } } static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); index_type i (0); for (typename container_type::const_iterator j (c.begin ()), e (c.end ()); j != e; ++j) - f.insert_one (i++, *j); + f.insert (i++, *j); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; } diff --git a/odb/qt/containers/qlist-traits.hxx b/odb/qt/containers/qlist-traits.hxx index 82eacca..720074c 100644 --- a/odb/qt/containers/qlist-traits.hxx +++ b/odb/qt/containers/qlist-traits.hxx @@ -18,6 +18,7 @@ namespace odb { public: static const container_kind kind = ck_ordered; + static const bool smart = false; typedef QList container_type; @@ -34,7 +35,7 @@ namespace odb // QList. // for (index_type i (0), n (c.size ()); i < n; ++i) - f.insert_one (i, c[i]); + f.insert (i, c[i]); } static void @@ -46,23 +47,23 @@ namespace odb { index_type dummy; c.append (value_type ()); - more = f.load_all (dummy, c.back ()); + more = f.select (dummy, c.back ()); } } static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (index_type i (0), n (c.size ()); i < n; ++i) - f.insert_one (i, c[i]); + f.insert (i, c[i]); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; } diff --git a/odb/qt/containers/qmap-traits.hxx b/odb/qt/containers/qmap-traits.hxx index e9c422c..db81715 100644 --- a/odb/qt/containers/qmap-traits.hxx +++ b/odb/qt/containers/qmap-traits.hxx @@ -19,6 +19,7 @@ namespace odb { public: static const container_kind kind = ck_map; + static const bool smart = false; typedef QMap container_type; @@ -33,7 +34,7 @@ namespace odb { for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void @@ -45,7 +46,7 @@ namespace odb { key_type k; value_type v; - more = f.load_all (k, v); + more = f.select (k, v); c.insert (k, v); //@@ Use std::move in C++11. } } @@ -53,17 +54,17 @@ namespace odb static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; // @@ QMultiMap guarantees elements to be stored in reverse order of @@ -75,6 +76,7 @@ namespace odb { public: static const container_kind kind = ck_multimap; + static const bool smart = false; typedef QMultiMap container_type; @@ -89,7 +91,7 @@ namespace odb { for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void @@ -101,7 +103,7 @@ namespace odb { key_type k; value_type v; - more = f.load_all (k, v); + more = f.select (k, v); c.insert (k, v); //@@ Use std::move in C++11. } } @@ -109,17 +111,17 @@ namespace odb static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (i.key (), i.value ()); + f.insert (i.key (), i.value ()); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; } diff --git a/odb/qt/containers/qset-traits.hxx b/odb/qt/containers/qset-traits.hxx index 1d99321..f83ad4d 100644 --- a/odb/qt/containers/qset-traits.hxx +++ b/odb/qt/containers/qset-traits.hxx @@ -18,6 +18,7 @@ namespace odb { public: static const container_kind kind = ck_set; + static const bool smart = false; typedef QSet container_type; typedef T value_type; @@ -30,7 +31,7 @@ namespace odb { for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (*i); + f.insert (*i); } static void @@ -41,7 +42,7 @@ namespace odb while (more) { value_type v; - more = f.load_all (v); + more = f.select (v); c.insert (v); //@@ Use std::move in C++11. } } @@ -49,17 +50,17 @@ namespace odb static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (typename container_type::const_iterator i (c.begin ()), e (c.end ()); i != e; ++i) - f.insert_one (*i); + f.insert (*i); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; } diff --git a/odb/qt/containers/qvector-traits.hxx b/odb/qt/containers/qvector-traits.hxx index c3dfb5b..79b9d4b 100644 --- a/odb/qt/containers/qvector-traits.hxx +++ b/odb/qt/containers/qvector-traits.hxx @@ -18,6 +18,7 @@ namespace odb { public: static const container_kind kind = ck_ordered; + static const bool smart = false; typedef QVector container_type; @@ -34,7 +35,7 @@ namespace odb // QVector. // for (index_type i (0), n (c.size ()); i < n; ++i) - f.insert_one (i, c[i]); + f.insert (i, c[i]); } static void @@ -46,23 +47,23 @@ namespace odb { index_type dummy; c.append (value_type ()); - more = f.load_all (dummy, c.back ()); + more = f.select (dummy, c.back ()); } } static void update (const container_type& c, const functions& f) { - f.delete_all (); + f.delete_ (); for (index_type i (0), n (c.size ()); i < n; ++i) - f.insert_one (i, c[i]); + f.insert (i, c[i]); } static void erase (const functions& f) { - f.delete_all (); + f.delete_ (); } }; } diff --git a/odb/qt/list-iterator.hxx b/odb/qt/list-iterator.hxx new file mode 100644 index 0000000..e2cbb7d --- /dev/null +++ b/odb/qt/list-iterator.hxx @@ -0,0 +1,10 @@ +// file : odb/qt/list-iterator.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_LIST_ITERATOR_HXX +#define ODB_QT_LIST_ITERATOR_HXX + +#include + +#endif // ODB_QT_LIST_ITERATOR_HXX diff --git a/odb/qt/list.hxx b/odb/qt/list.hxx new file mode 100644 index 0000000..fa6ed28 --- /dev/null +++ b/odb/qt/list.hxx @@ -0,0 +1,10 @@ +// file : odb/qt/list.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_LIST_HXX +#define ODB_QT_LIST_HXX + +#include + +#endif // ODB_QT_LIST_HXX diff --git a/odb/qt/mutable-list-iterator.hxx b/odb/qt/mutable-list-iterator.hxx new file mode 100644 index 0000000..3a94530 --- /dev/null +++ b/odb/qt/mutable-list-iterator.hxx @@ -0,0 +1,10 @@ +// file : odb/qt/mutable-list-iterator.hxx +// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_MUTABLE_LIST_ITERATOR_HXX +#define ODB_QT_MUTABLE_LIST_ITERATOR_HXX + +#include + +#endif // ODB_QT_MUTABLE_LIST_ITERATOR_HXX -- cgit v1.1