From 55f7c6da84f5368373e46945e4f6bee28f53cb81 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 12 Feb 2013 11:01:50 +0200 Subject: Workarounds for non-standard Sun CC STL --- odb/vector.hxx | 166 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 41 deletions(-) (limited to 'odb/vector.hxx') diff --git a/odb/vector.hxx b/odb/vector.hxx index 5f1371a..6aeab25 100644 --- a/odb/vector.hxx +++ b/odb/vector.hxx @@ -10,6 +10,7 @@ #include #include +#include // std::ptrdiff_t #ifdef ODB_CXX11 # include // std::move, std::forward @@ -20,6 +21,22 @@ #include +// Because both std::vector and odb::vector are called 'vector' (who +// cares about namespace qualifications, right?), Sun CC complains +// with a bogus "Ambiguous partial specialization" error. A really +// hideous workaround for this bug is to to add a dummy third template +// argument (with a default value). +// +#ifdef __SUNPRO_CC +# define LIBODB_VECTOR_ARG_DEFAULT ,int = 0 +# define LIBODB_VECTOR_ARG_DECL ,int DUMMY +# define LIBODB_VECTOR_ARG_USE ,DUMMY +#else +# define LIBODB_VECTOR_ARG_DEFAULT +# define LIBODB_VECTOR_ARG_DECL +# define LIBODB_VECTOR_ARG_USE +#endif + namespace odb { // An std::vector-like container that keeps track of changes. @@ -30,7 +47,7 @@ namespace odb template class vector_iterator; - template > + template LIBODB_VECTOR_ARG_DEFAULT> class vector: public vector_base { public: @@ -50,8 +67,12 @@ namespace odb typedef A allocator_type; typedef typename base_vector_type::pointer pointer; typedef typename base_vector_type::const_pointer const_pointer; + // No non-const reverse iterator support for Sun CC with non-standard STL. + // +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC typedef vector_iterator reverse_iterator; +#endif typedef typename base_vector_type::const_reverse_iterator const_reverse_iterator; // construct/copy/destroy: @@ -86,12 +107,14 @@ namespace odb // 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 begin() const {return v_.begin ();} const_iterator end() const {return v_.end ();} +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC 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 ());} +#endif + const_reverse_iterator rbegin() const {return v_.rbegin ();} const_reverse_iterator rend() const {return v_.rend ();} // Return standard vector iterators. The begin() functions mark all @@ -203,68 +226,84 @@ namespace odb using odb::vector; } - template - inline bool operator==(const vector& x, const vector& y) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + 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) + template + inline bool operator<=(const std::vector& x, + const vector& y) {return x <= y.base ();} template @@ -274,6 +313,10 @@ namespace odb typedef V vector_type; typedef I base_iterator_type; typedef typename vector_type::const_iterator const_iterator_type; + + // Sun CC with non-standard STL does not have iterator_traits. + // +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC typedef std::iterator_traits base_iterator_traits; typedef typename base_iterator_traits::value_type value_type; @@ -281,6 +324,15 @@ namespace odb typedef typename base_iterator_traits::pointer pointer; typedef typename base_iterator_traits::reference reference; typedef typename base_iterator_traits::iterator_category iterator_category; +#else + // Base iterator is just a pointer. + // + typedef typename vector_type::value_type value_type; + typedef typename vector_type::pointer pointer; + typedef typename vector_type::reference reference; + typedef std::random_access_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; +#endif typedef typename vector_type::size_type size_type; typedef typename vector_type::const_reference const_reference; @@ -301,8 +353,23 @@ namespace odb // Modifiers. // - reference modify () const; - reference modify (difference_type n) const; + // Buggy Sun CC cannot have them out of class. + // + reference modify () const + { + if (v_->_tracking ()) + v_->_impl ().modify ( + static_cast (i_ - v_->base ().begin ())); + return *i_; + } + + reference modify (difference_type n) const + { + if (v_->_tracking ()) + v_->_impl ().modify ( + static_cast (i_ - v_->base ().begin () + n)); + return i_[n]; + } vector_iterator& operator++ () {++i_; return *this;} vector_iterator operator++ (int) {return vector_iterator (v_, i_++);} @@ -326,6 +393,7 @@ namespace odb base_iterator_type i_; }; +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC template class vector_iterator > { @@ -364,8 +432,22 @@ namespace odb // Modifiers. // - reference modify () const; - reference modify (difference_type n) const; + reference modify () const + { + if (v_->_tracking ()) + v_->_impl ().modify ( + static_cast (v_->base ().rend () - i_ - 1)); + return *i_; + } + + reference 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]; + } vector_iterator& operator++ () {++i_; return *this;} vector_iterator operator++ (int) {return vector_iterator (v_, i_++);} @@ -388,6 +470,7 @@ namespace odb vector_type* v_; base_iterator_type i_; }; +#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC // operator== // @@ -533,8 +616,9 @@ namespace odb namespace std { - template - inline void swap(odb::vector& x, odb::vector& y) {x.swap (y);} + template + inline void swap(odb::vector& x, + odb::vector& y) {x.swap (y);} } #include -- cgit v1.1