Rework iterator template again for Sun's broken STL.
authorcantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Tue, 13 Nov 2007 21:14:25 +0000 (21:14 +0000)
committercantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Tue, 13 Nov 2007 21:14:25 +0000 (21:14 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/trunk@430 de75baf8-a10c-0410-a50a-987c0e22f00f

config_win32.h
configure.ac
xmltooling/config_pub.h.in
xmltooling/config_pub_win32.h
xmltooling/util/XMLObjectChildrenList.h

index 63a1a56..966b4d3 100644 (file)
    specialization. */
 #define HAVE_GOOD_STL 1
 
+/* Defne to 1 if you have an STL implementation that supports
+   std::iterator_traits. */
+#define HAVE_ITERATOR_TRAITS 1
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 /* #undef HAVE_INTTYPES_H */
 
index e70c47f..fe1063a 100644 (file)
@@ -297,6 +297,12 @@ AC_TRY_LINK(
         [AC_DEFINE(HAVE_GOOD_STL,1,
             [Define if you have an STL implementation that supports useful string specialization.])],
         )
+AC_TRY_LINK(
+        [#include <vector>],
+        [std::iterator_traits<std::vector<int>::iterator>::value_type foo=0],
+        [AC_DEFINE(HAVE_ITERATOR_TRAITS,1,
+            [Defne to 1 if you have an STL implementation that supports std::iterator_traits.])],
+        )
 
 # Check for unit test support
 CXXTEST="/usr/bin/cxxtestgen.pl"
index 144d787..a3df263 100644 (file)
@@ -5,6 +5,10 @@
    specialization. */
 #undef HAVE_GOOD_STL
 
+/* Defne to 1 if you have an STL implementation that supports
+   std::iterator_traits. */
+#undef HAVE_ITERATOR_TRAITS
+
 /* Define if log4shib library is used. */
 #undef XMLTOOLING_LOG4SHIB
 
index 0c13ee2..75111c2 100644 (file)
@@ -5,6 +5,10 @@
    specialization. */
 #define HAVE_GOOD_STL 1
 
+/* Defne to 1 if you have an STL implementation that supports
+   std::iterator_traits. */
+#define HAVE_ITERATOR_TRAITS 1
+
 /* Define if log4shib library is used. */
 #define XMLTOOLING_LOG4SHIB 1
 
index f897df0..95f5c4c 100644 (file)
@@ -81,28 +81,261 @@ namespace xmltooling {
 
     /**
      * STL iterator that mediates access to an iterator over typed XML children.
-     * @param _Ty   a bidrectional sequence of the subtype to iterate over
+     *
+     * @param Container type of container
+     * @param _Ty       a bidrectional iterator to guard
      */
-    template <class _Ty>
+    template <class Container, typename _Ty>
     class XMLObjectChildrenIterator
     {
         /// @cond OFF
-        typename _Ty::iterator m_iter;
+        typename _Ty m_iter;
         template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
         template <class _Tx, class _Tz> friend class XMLObjectPairList;
     public:
-        typedef typename std::iterator_traits<typename _Ty::iterator>::iterator_category iterator_category;
-        typedef typename std::iterator_traits<typename _Ty::iterator>::value_type value_type;
-        typedef typename std::iterator_traits<typename _Ty::iterator>::difference_type difference_type;
-        typedef typename std::iterator_traits<typename _Ty::iterator>::pointer pointer;
-        typedef typename std::iterator_traits<typename _Ty::iterator>::reference reference;
-        typedef typename _Ty::const_reference const_reference;
-        typedef typename _Ty::const_pointer const_pointer;
+#ifdef HAVE_ITERATOR_TRAITS
+        typedef typename std::iterator_traits<_Ty>::iterator_category iterator_category;
+        typedef typename std::iterator_traits<_Ty>::value_type value_type;
+        typedef typename std::iterator_traits<_Ty>::difference_type difference_type;
+        typedef typename std::iterator_traits<_Ty>::pointer pointer;
+        typedef typename std::iterator_traits<_Ty>::reference reference;
+#else
+        typedef typename _Ty::iterator_category iterator_category;
+        typedef typename _Ty::value_type value_type;
+        typedef typename _Ty::difference_type difference_type;
+        typedef typename _Ty::pointer pointer;
+        typedef typename _Ty::reference reference;
+#endif
+        typedef typename Container::const_reference const_reference;
+        typedef typename Container::const_pointer const_pointer;
+
+        XMLObjectChildrenIterator() {
+        }
+
+        XMLObjectChildrenIterator(_Ty iter) {
+            m_iter=iter;
+        }
+
+        const_reference operator*() const {
+            return *m_iter;
+        }
+
+        const_reference operator->() const {
+            return *m_iter;
+        }
+
+        XMLObjectChildrenIterator& operator++() {
+            // preincrement
+            ++m_iter;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator& operator--() {
+            // predecrement
+            --m_iter;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator operator++(int) {
+            // postincrement
+            XMLObjectChildrenIterator _Tmp = *this;
+            ++*this;
+            return (_Tmp);
+        }
+
+        XMLObjectChildrenIterator operator--(int) {
+            // postdecrement
+            XMLObjectChildrenIterator _Tmp = *this;
+            --*this;
+            return (_Tmp);
+        }
+
+        XMLObjectChildrenIterator& operator+=(difference_type _Off) {
+            // increment by integer
+            m_iter += _Off;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator operator+(difference_type _Off) const {
+            // return this + integer
+            return m_iter + _Off;
+        }
+
+        XMLObjectChildrenIterator& operator-=(difference_type _Off) {
+            // decrement by integer
+            return (*this += -_Off);
+        }
+
+        XMLObjectChildrenIterator operator-(difference_type _Off) const {
+            // return this - integer
+            XMLObjectChildrenIterator _Tmp = *this;
+            return (_Tmp -= _Off);
+        }
+
+        difference_type operator-(const XMLObjectChildrenIterator& _Right) const {
+            // return difference of iterators
+            return m_iter - _Right.m_iter;
+        }
+
+        const_reference operator[](difference_type _Off) const {
+            // subscript
+            return (*(*this + _Off));
+        }
+
+        bool operator==(const XMLObjectChildrenIterator &_Right) const {
+                   // test for iterator equality
+                   return (m_iter == _Right.m_iter);
+           }
+
+           bool operator!=(const XMLObjectChildrenIterator &_Right) const {
+                   // test for iterator inequality
+                   return (!(m_iter == _Right.m_iter));
+           }
+           
+           bool operator<(const XMLObjectChildrenIterator &_Right) const {
+               return (m_iter < _Right.m_iter);
+           }
+        /// @endcond
+    };
+
+#ifndef HAVE_ITERATOR_TRAITS
+    /**
+     * STL iterator that mediates access to an iterator that's a pointer.
+     *
+     * @param Container type of container
+     * @param _Ty       the type of object being referenced
+     */
+    template <class Container, typename _Ty>
+    class XMLObjectChildrenIterator<Container, _Ty*>
+    {
+        /// @cond OFF
+        typename _Ty* m_iter;
+        template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
+        template <class _Tx, class _Tz> friend class XMLObjectPairList;
+    public:
+        typedef std::random_access_iterator_tag iterator_category;
+        typedef _Ty value_type;
+        typedef ptrdiff_t difference_type;
+        typedef _Ty* pointer;
+        typedef _Ty& reference;
+        typedef const _Ty& const_reference;
+        typedef const _Ty* const_pointer;
+
+        XMLObjectChildrenIterator() {
+        }
+
+        XMLObjectChildrenIterator(_Ty* iter) {
+            m_iter=iter;
+        }
+
+        const_reference operator*() const {
+            return *m_iter;
+        }
+
+        const_reference operator->() const {
+            return *m_iter;
+        }
+
+        XMLObjectChildrenIterator& operator++() {
+            // preincrement
+            ++m_iter;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator& operator--() {
+            // predecrement
+            --m_iter;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator operator++(int) {
+            // postincrement
+            XMLObjectChildrenIterator _Tmp = *this;
+            ++*this;
+            return (_Tmp);
+        }
+
+        XMLObjectChildrenIterator operator--(int) {
+            // postdecrement
+            XMLObjectChildrenIterator _Tmp = *this;
+            --*this;
+            return (_Tmp);
+        }
+
+        XMLObjectChildrenIterator& operator+=(difference_type _Off) {
+            // increment by integer
+            m_iter += _Off;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator operator+(difference_type _Off) const {
+            // return this + integer
+            return m_iter + _Off;
+        }
+
+        XMLObjectChildrenIterator& operator-=(difference_type _Off) {
+            // decrement by integer
+            return (*this += -_Off);
+        }
+
+        XMLObjectChildrenIterator operator-(difference_type _Off) const {
+            // return this - integer
+            XMLObjectChildrenIterator _Tmp = *this;
+            return (_Tmp -= _Off);
+        }
+
+        difference_type operator-(const XMLObjectChildrenIterator& _Right) const {
+            // return difference of iterators
+            return m_iter - _Right.m_iter;
+        }
+
+        const_reference operator[](difference_type _Off) const {
+            // subscript
+            return (*(*this + _Off));
+        }
+
+        bool operator==(const XMLObjectChildrenIterator &_Right) const {
+                   // test for iterator equality
+                   return (m_iter == _Right.m_iter);
+           }
+
+           bool operator!=(const XMLObjectChildrenIterator &_Right) const {
+                   // test for iterator inequality
+                   return (!(m_iter == _Right.m_iter));
+           }
+           
+           bool operator<(const XMLObjectChildrenIterator &_Right) const {
+               return (m_iter < _Right.m_iter);
+           }
+        /// @endcond
+    };
+
+    /**
+     * STL iterator that mediates access to an iterator that's a const pointer.
+     *
+     * @param Container type of container
+     * @param _Ty       the type of object being referenced
+     */
+    template <class Container, typename _Ty>
+    class XMLObjectChildrenIterator<Container, const _Ty*>
+    {
+        /// @cond OFF
+        typename const _Ty* m_iter;
+        template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
+        template <class _Tx, class _Tz> friend class XMLObjectPairList;
+    public:
+        typedef std::random_access_iterator_tag iterator_category;
+        typedef _Ty value_type;
+        typedef ptrdiff_t difference_type;
+        typedef const _Ty* pointer;
+        typedef const _Ty& reference;
+        typedef const _Ty& const_reference;
+        typedef const _Ty* const_pointer;
 
         XMLObjectChildrenIterator() {
         }
 
-        XMLObjectChildrenIterator(typename _Ty::iterator iter) {
+        XMLObjectChildrenIterator(_Ty* iter) {
             m_iter=iter;
         }
 
@@ -187,6 +420,7 @@ namespace xmltooling {
            }
         /// @endcond
     };
+#endif
 
     /**
      * STL-compatible container that mediates access to underlying lists of typed XML children.
@@ -210,8 +444,8 @@ namespace xmltooling {
         typedef typename Container::size_type size_type;
 
         // We override the iterator types with our constrained wrapper.
-        typedef XMLObjectChildrenIterator<Container> iterator;
-        typedef XMLObjectChildrenIterator<Container> const_iterator;
+        typedef XMLObjectChildrenIterator<Container, typename Container::iterator> iterator;
+        typedef XMLObjectChildrenIterator<Container, typename Container::const_iterator> const_iterator;
         /// @endcond
 
         /**
@@ -364,8 +598,8 @@ namespace xmltooling {
         typedef typename Container::size_type size_type;
 
         // We override the iterator types with our constrained wrapper.
-        typedef XMLObjectChildrenIterator<Container> iterator;
-        typedef XMLObjectChildrenIterator<Container> const_iterator;
+        typedef XMLObjectChildrenIterator<Container, typename Container::iterator> iterator;
+        typedef XMLObjectChildrenIterator<Container, typename Container::const_iterator> const_iterator;
         /// @endcond
 
         /**