From 1f24efd1ed68c61915af85793dd547987bea852d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Wed, 24 Sep 2014 15:28:44 +0200 Subject: [PATCH] Implemented N3644 (Null Forward Iterators) --- doc/intrusive.qbk | 1 + .../boost/intrusive/detail/hashtable_node.hpp | 1 + include/boost/intrusive/detail/iterator.hpp | 137 ++++++++++++++++++ include/boost/intrusive/detail/utilities.hpp | 114 +-------------- proj/vc7ide/Intrusive.sln | 8 + .../vc7ide/_intrusivelib/_intrusivelib.vcproj | 3 + .../vc7ide/null_iterator/null_iterator.vcproj | 128 ++++++++++++++++ test/null_iterator_test.cpp | 98 +++++++++++++ 8 files changed, 380 insertions(+), 110 deletions(-) create mode 100644 include/boost/intrusive/detail/iterator.hpp create mode 100644 proj/vc7ide/null_iterator/null_iterator.vcproj create mode 100644 test/null_iterator_test.cpp diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index d3c93f2..de7fb77 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3764,6 +3764,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std [section:release_notes_boost_1_57_00 Boost 1.57 Release] * Experimental version of node checkers, contributed by Matei David. Many thanks! +* Implemented [@http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf N3644: Null Forward Iterators] from C++14. * Fixed bugs: * [@https://github.com/boostorg/intrusive/pull/12 GitHub #12: ['Fix MSVC14 warning C4456: declaration of 'x_parent_right' hides previous local declaration]] diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index 68122f0..40b1f35 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -256,6 +256,7 @@ class hashtable_iterator typedef typename iterator_traits::iterator_category iterator_category; hashtable_iterator () + : slist_it_() //Value initialization to achieve "null iterators" (N3644) {} explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont) diff --git a/include/boost/intrusive/detail/iterator.hpp b/include/boost/intrusive/detail/iterator.hpp new file mode 100644 index 0000000..7495ef9 --- /dev/null +++ b/include/boost/intrusive/detail/iterator.hpp @@ -0,0 +1,137 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP + +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class reverse_iterator + : public std::iterator< + typename std::iterator_traits::iterator_category, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference> +{ + public: + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef It iterator_type; + + reverse_iterator() + : m_current() //Value initialization to achieve "null iterators" (N3644) + {} + + explicit reverse_iterator(It r) + : m_current(r) + {} + + template + reverse_iterator(const reverse_iterator& r) + : m_current(r.base()) + {} + + It base() const + { return m_current; } + + reference operator*() const + { It temp(m_current); --temp; return *temp; } + + pointer operator->() const + { It temp(m_current); --temp; return temp.operator->(); } + + reference operator[](difference_type off) const + { return this->m_current[-off]; } + + reverse_iterator& operator++() + { --m_current; return *this; } + + reverse_iterator operator++(int) + { + reverse_iterator temp = *this; + --m_current; + return temp; + } + + reverse_iterator& operator--() + { + ++m_current; + return *this; + } + + reverse_iterator operator--(int) + { + reverse_iterator temp(*this); + ++m_current; + return temp; + } + + friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current == r.m_current; } + + friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current != r.m_current; } + + friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current < r.m_current; } + + friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current <= r.m_current; } + + friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current > r.m_current; } + + friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current >= r.m_current; } + + reverse_iterator& operator+=(difference_type off) + { m_current -= off; return *this; } + + friend reverse_iterator operator+(const reverse_iterator & l, difference_type off) + { + reverse_iterator tmp(l.m_current); + tmp.m_current -= off; + return tmp; + } + + reverse_iterator& operator-=(difference_type off) + { m_current += off; return *this; } + + friend reverse_iterator operator-(const reverse_iterator & l, difference_type off) + { + reverse_iterator tmp(l.m_current); + tmp.m_current += off; + return tmp; + } + + friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) + { return r.m_current - l.m_current; } + + private: + It m_current; // the wrapped iterator +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index 60fbbb7..f51b45a 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -796,116 +797,7 @@ class array_initializer private: detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; }; - - - - -template -class reverse_iterator - : public std::iterator< - typename std::iterator_traits::iterator_category, - typename std::iterator_traits::value_type, - typename std::iterator_traits::difference_type, - typename std::iterator_traits::pointer, - typename std::iterator_traits::reference> -{ - public: - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::difference_type difference_type; - typedef It iterator_type; - - reverse_iterator(){} - - explicit reverse_iterator(It r) - : m_current(r) - {} - - template - reverse_iterator(const reverse_iterator& r) - : m_current(r.base()) - {} - - It base() const - { return m_current; } - - reference operator*() const - { It temp(m_current); --temp; return *temp; } - - pointer operator->() const - { It temp(m_current); --temp; return temp.operator->(); } - - reference operator[](difference_type off) const - { return this->m_current[-off]; } - - reverse_iterator& operator++() - { --m_current; return *this; } - - reverse_iterator operator++(int) - { - reverse_iterator temp = *this; - --m_current; - return temp; - } - - reverse_iterator& operator--() - { - ++m_current; - return *this; - } - - reverse_iterator operator--(int) - { - reverse_iterator temp(*this); - ++m_current; - return temp; - } - - friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current == r.m_current; } - - friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current != r.m_current; } - - friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current < r.m_current; } - - friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current <= r.m_current; } - - friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current > r.m_current; } - - friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current >= r.m_current; } - - reverse_iterator& operator+=(difference_type off) - { m_current -= off; return *this; } - - friend reverse_iterator operator+(const reverse_iterator & l, difference_type off) - { - reverse_iterator tmp(l.m_current); - tmp.m_current -= off; - return tmp; - } - - reverse_iterator& operator-=(difference_type off) - { m_current += off; return *this; } - - friend reverse_iterator operator-(const reverse_iterator & l, difference_type off) - { - reverse_iterator tmp(l.m_current); - tmp.m_current += off; - return tmp; - } - - friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) - { return r.m_current - l.m_current; } - - private: - It m_current; // the wrapped iterator -}; - + template struct uncast_types { @@ -1223,6 +1115,7 @@ struct iiterator_members { iiterator_members() + : nodeptr_()//Value initialization to achieve "null iterators" (N3644) {} iiterator_members(const NodePtr &n_ptr, const StoredPointer &data) @@ -1240,6 +1133,7 @@ template struct iiterator_members { iiterator_members() + : nodeptr_()//Value initialization to achieve "null iterators" (N3644) {} iiterator_members(const NodePtr &n_ptr, const StoredPointer &) diff --git a/proj/vc7ide/Intrusive.sln b/proj/vc7ide/Intrusive.sln index ce7d63d..03b1e17 100644 --- a/proj/vc7ide/Intrusive.sln +++ b/proj/vc7ide/Intrusive.sln @@ -123,6 +123,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parent_from_member", "paren ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_iterator", "null_iterator\null_iterator.vcproj", "{32A79B10-B2A0-C1B8-9458-9456152413B5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -255,6 +259,10 @@ Global {3A279B10-2A0B-B8C1-5894-9461524135B5}.Debug.Build.0 = Debug|Win32 {3A279B10-2A0B-B8C1-5894-9461524135B5}.Release.ActiveCfg = Release|Win32 {3A279B10-2A0B-B8C1-5894-9461524135B5}.Release.Build.0 = Release|Win32 + {32A79B10-B2A0-C1B8-9458-9456152413B5}.Debug.ActiveCfg = Debug|Win32 + {32A79B10-B2A0-C1B8-9458-9456152413B5}.Debug.Build.0 = Debug|Win32 + {32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.ActiveCfg = Release|Win32 + {32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj index b441854..51a4c1b 100644 --- a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj +++ b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj @@ -259,6 +259,9 @@ + + diff --git a/proj/vc7ide/null_iterator/null_iterator.vcproj b/proj/vc7ide/null_iterator/null_iterator.vcproj new file mode 100644 index 0000000..89d854a --- /dev/null +++ b/proj/vc7ide/null_iterator/null_iterator.vcproj @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/null_iterator_test.cpp b/test/null_iterator_test.cpp new file mode 100644 index 0000000..7b7d72d --- /dev/null +++ b/test/null_iterator_test.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Howard Hinnant 2014. +// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace boost::intrusive; + + +#include +struct Type + : list_base_hook<> + , slist_base_hook<> + , set_base_hook<> + , avl_set_base_hook<> + , bs_set_base_hook<> +{}; + +typedef boost::aligned_storage::type buffer_t; + +static buffer_t buffer_0x00; +static buffer_t buffer_0xFF; + +template +const Iterator &on_0x00_buffer() +{ + BOOST_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator)); + return * ::new(std::memset(&buffer_0x00, 0x00, sizeof(buffer_0x00))) Iterator(); +} + +template +const Iterator &on_0xFF_buffer() +{ + BOOST_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator)); + return * ::new(std::memset(&buffer_0xFF, 0xFF, sizeof(buffer_0xFF))) Iterator(); +} + +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reverse_iterator) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator) + + +template +void check_null_iterators() +{ + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (::, Container + ,reverse_iterator, iterator) reverse_iterator; + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (::, Container + ,const_reverse_iterator, const_iterator) const_reverse_iterator; + + BOOST_TEST(on_0xFF_buffer() == on_0x00_buffer()); + BOOST_TEST(on_0xFF_buffer() == on_0x00_buffer()); + BOOST_TEST(on_0xFF_buffer() == on_0x00_buffer()); + BOOST_TEST(on_0xFF_buffer() == on_0x00_buffer()); +} + +int main() +{ + check_null_iterators< list >(); + check_null_iterators< slist >(); + check_null_iterators< bs_set >(); + check_null_iterators< set >(); + check_null_iterators< multiset >(); + check_null_iterators< avl_set >(); + check_null_iterators< avl_multiset >(); + check_null_iterators< sg_set >(); + check_null_iterators< sg_multiset >(); + check_null_iterators< treap_set >(); + check_null_iterators< treap_multiset >(); + check_null_iterators< splay_set >(); + check_null_iterators< splay_multiset >(); + + return boost::report_errors(); +}