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.ixx | 397 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 odb/vector.ixx (limited to 'odb/vector.ixx') diff --git a/odb/vector.ixx b/odb/vector.ixx new file mode 100644 index 0000000..1e36fe1 --- /dev/null +++ b/odb/vector.ixx @@ -0,0 +1,397 @@ +// file : odb/vector.ixx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + // + // vector + // + + // construct/copy/destroy: + // + template + inline vector& vector:: + operator= (const vector& x) + { + v_ = x.v_; + if (_tracking ()) + impl_.assign (v_.size ()); + return *this; + } + + template + template + inline void vector:: + assign (I f, I l) + { + v_.assign (f, l); + if (_tracking ()) + impl_.assign (v_.size ()); + } + + template + inline void vector:: + assign (size_type n, const T& u) + { + v_.assign (n, u); + if (_tracking ()) + impl_.assign (n); + } + +#ifdef ODB_CXX11 + template + inline vector& vector:: + vector& operator=(vector&& x) + { + v_ = std::move (x.v_); + if (_tracking ()) + impl_.assign (v_.size ()); + return *this; + } + +#ifdef ODB_CXX11_INITIALIZER_LIST + template + inline vector& vector:: + operator= (std::initializer_list il) + { + v_ = il; + if (_tracking ()) + impl_.assign (v_.size ()); + return *this; + } + + template + inline void vector:: + assign (std::initializer_list il) + { + v_.assign (il); + if (_tracking ()) + impl_.assign (v_.size ()); + } +#endif +#endif + + // iterators: + // + template + inline typename vector::base_iterator_type vector:: + mbegin () + { + if (_tracking ()) + impl_.modify (0, v_.size ()); + return v_.begin (); + } + + template + inline typename vector::base_reverse_iterator_type vector:: + mrbegin () + { + if (_tracking ()) + impl_.modify (0, v_.size ()); + return v_.rbegin (); + } + + // capacity: + // + template + inline void vector:: + resize (size_type n) + { + v_.resize (n); + if (_tracking ()) + impl_.resize (n); + } + + template + inline void vector:: + resize (size_type n, const T& c) + { + v_.resize (n, c); + if (_tracking ()) + impl_.resize (n); + } + + template + inline void vector:: + reserve (size_type n) + { + v_.reserve (n); + if (_tracking ()) + impl_.reserve (n); + } + +#ifdef ODB_CXX11 + template + inline void vector:: + shrink_to_fit () + { + v_.shrink_to_fit (); + impl_.shrink_to_fit (); + } +#endif + + // element access: + // + template + inline typename vector::reference vector:: + modify (size_type n) + { + reference& r (v_[n]); + if (_tracking ()) + impl_.modify (n); + return r; + } + + template + inline typename vector::reference vector:: + modify_at (size_type n) + { + reference& r (v_.at (n)); + if (_tracking ()) + impl_.modify (n); + return r; + } + + template + inline typename vector::reference vector:: + modify_front () + { + reference& r (v_.front ()); + if (_tracking ()) + impl_.modify (0); + return r; + } + + template + inline typename vector::reference vector:: + modify_back () + { + reference& r (v_.back ()); + if (_tracking ()) + impl_.modify (v_.size () - 1); + return r; + } + +#ifdef ODB_CXX11 + template + inline T* vector:: + modify_data() /*noexcept*/ + { + if (_tracking ()) + impl_.modify (0, v_.size ()); + return v_.data (); + } +#endif + + // modifiers: + // + template + inline void vector:: + push_back (const T& x) + { + v_.push_back (x); + if (_tracking ()) + impl_.push_back (); + } + + template + inline void vector:: + pop_back () + { + v_.pop_back (); + if (_tracking ()) + impl_.pop_back (); + } + + template + inline typename vector::iterator vector:: + insert (iterator p, const T& x) + { + if (_tracking ()) + impl_.insert (static_cast (p.base () - v_.begin ())); + return iterator (this, v_.insert (p.base (), x)); + } + + template + inline void vector:: + insert (iterator p, size_type n, const T& x) + { + if (_tracking ()) + impl_.insert (static_cast (p.base () - v_.begin ()), n); + v_.insert (p.base (), n, x); + } + + template + template + inline void vector:: + insert (iterator p, I f, I l) + { + size_type i, n; + if (_tracking ()) + { + i = static_cast (p.base () - v_.begin ()); + n = v_.size (); + } + + v_.insert (p.base (), f, l); + + if (_tracking ()) + impl_.insert (i, v_.size () - n); + } + + template + inline typename vector::iterator vector:: + erase (iterator p) + { + if (_tracking ()) + impl_.erase (static_cast (p.base () - v_.begin ())); + return iterator (this, v_.erase (p.base ())); + } + + template + inline typename vector::iterator vector:: + erase (iterator f, iterator l) + { + if (_tracking ()) + impl_.erase (static_cast (f.base () - v_.begin ()), + static_cast (l - f)); + return iterator (this, v_.erase (f.base (), l.base ())); + } + + template + inline void vector:: + swap (vector& x) + { + v_.swap (x.v_); + vector_base::swap (x); + } + + template + inline void vector:: + clear () + { + v_.clear (); + if (_tracking ()) + impl_.clear (); + } + +#ifdef ODB_CXX11 + template + inline void vector:: + push_back(T&& x) + { + v_.push_back (std::move (x)); + if (_tracking ()) + impl_.push_back (); + } + + template + inline typename vector::iterator vector:: + insert (iterator p, T&& x) + { + base_iterator_type r (v_.insert (p.base (), std::move (x))); + if (_tracking ()) + impl_.insert (static_cast (r - v_.begin ())); + return iterator (this, r); + } + +#ifdef ODB_CXX11_VARIADIC_TEMPLATE + template + template + inline void vector:: + emplace_back (Args&&... args) + { + v_.push_back (std::forward (args)...); + if (_tracking ()) + impl_.push_back (); + } + + template + template + inline typename vector::iterator vector:: + emplace (iterator p, Args&&... args) + { + base_iterator_type r ( + v_.emplace (p.base (), std::forward (args)...)); + if (_tracking ()) + impl_.insert (static_cast (r - v_.begin ())); + return iterator (this, r); + } +#endif +#endif + + // Interfacing with base vector. + // + template + inline vector& vector:: + operator= (const base_vector_type& x) + { + v_ = x; + if (_tracking ()) + impl_.assign (v_.size ()); + return *this; + } + +#ifdef ODB_CXX11 + template + inline vector& vector:: + operator= (base_vector_type&& x) + { + v_ = std::move (x); + if (_tracking ()) + impl_.assign (v_.size ()); + return *this; + } +#endif + + // + // vector_iterator + // + + template + inline typename vector_iterator::reference vector_iterator:: + modify () const + { + if (v_->_tracking ()) + v_->_impl ().modify (static_cast (i_ - v_->base ().begin ())); + return *i_; + } + + template + inline typename vector_iterator::reference vector_iterator:: + modify (difference_type n) const + { + if (v_->_tracking ()) + v_->_impl ().modify ( + static_cast (i_ - v_->base ().begin () + n)); + return i_[n]; + } + + // + // vector_iterator + // + + template + inline typename vector_iterator >::reference + vector_iterator >:: + modify () const + { + if (v_->_tracking ()) + v_->_impl ().modify ( + static_cast (v_->base ().rend () - i_ - 1)); + return *i_; + } + + template + inline typename vector_iterator >::reference + vector_iterator >:: + modify (difference_type n) const + { + if (v_->_tracking ()) + // Note: going in the opposite direction. + v_->_impl ().modify ( + static_cast (v_->base ().rend () - i_ - 1 - n)); + return i_[n]; + } +} -- cgit v1.1