From 5a67b76b0d9460fe7c97560f13c23cc65a47d8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 11 Aug 2024 21:34:29 +0200 Subject: [PATCH] Add BOOST_INTRUSIVE_NO_DANGLING ([[gnu::no_dangling]]) to avoid false positives on GCC 14 on container_from functions. --- doc/Jamfile.v2 | 1 + include/boost/intrusive/avl_set.hpp | 8 ++++++++ include/boost/intrusive/avltree.hpp | 4 ++++ include/boost/intrusive/bs_set.hpp | 8 ++++++++ include/boost/intrusive/bstree.hpp | 16 ++++++++++++---- include/boost/intrusive/detail/workaround.hpp | 10 ++++++++++ include/boost/intrusive/list.hpp | 5 +++++ include/boost/intrusive/rbtree.hpp | 4 ++++ include/boost/intrusive/set.hpp | 8 ++++++++ include/boost/intrusive/sg_set.hpp | 8 ++++++++ include/boost/intrusive/sgtree.hpp | 4 ++++ include/boost/intrusive/slist.hpp | 5 +++++ include/boost/intrusive/splay_set.hpp | 8 ++++++++ include/boost/intrusive/splaytree.hpp | 4 ++++ include/boost/intrusive/treap.hpp | 4 ++++ include/boost/intrusive/treap_set.hpp | 8 ++++++++ 16 files changed, 101 insertions(+), 4 deletions(-) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 73a729e4..386013c5 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -64,6 +64,7 @@ doxygen autodoc \"treap_multiset_impl=treap_multiset\" \\ \"treap_impl=treap\" \\ \"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template struct OPTION_NAME{};\" \\ + \"BOOST_INTRUSIVE_NO_DANGLING\" \\ \"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template struct OPTION_NAME{};\" " ; diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index 2d76ece7..5c0f8aa2 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -554,15 +554,19 @@ class avl_set inline void clone_from(BOOST_RV_REF(avl_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static avl_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const avl_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static avl_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const avl_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -1049,15 +1053,19 @@ class avl_multiset inline void clone_from(BOOST_RV_REF(avl_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static avl_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const avl_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static avl_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const avl_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 4eda39e6..09cdb525 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -564,15 +564,19 @@ class avltree inline void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static avltree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const avltree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static avltree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const avltree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/bs_set.hpp b/include/boost/intrusive/bs_set.hpp index c3275ddf..bb06d24a 100644 --- a/include/boost/intrusive/bs_set.hpp +++ b/include/boost/intrusive/bs_set.hpp @@ -551,15 +551,19 @@ class bs_set inline void clone_from(BOOST_RV_REF(bs_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static bs_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const bs_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static bs_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const bs_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -1045,15 +1049,19 @@ class bs_multiset inline void clone_from(BOOST_RV_REF(bs_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static bs_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const bs_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static bs_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const bs_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 8196d36b..6877bee2 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -876,7 +876,8 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Constant. - static bstree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT + BOOST_INTRUSIVE_NO_DANGLING + static bstree_impl& container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast (data_type::get_tree_base_from_end_iterator(end_iterator)); @@ -890,7 +891,8 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Constant. - static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT + BOOST_INTRUSIVE_NO_DANGLING + static const bstree_impl & container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast (data_type::get_tree_base_from_end_iterator(end_iterator)); @@ -904,7 +906,8 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Logarithmic. - static bstree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT + BOOST_INTRUSIVE_NO_DANGLING + static bstree_impl & container_from_iterator(iterator it) BOOST_NOEXCEPT { return container_from_end_iterator(it.end_iterator_from_it()); } //! Precondition: it must be a valid end const_iterator @@ -915,7 +918,8 @@ class bstree_impl //! Throws: Nothing. //! //! Complexity: Logarithmic. - static const bstree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT + BOOST_INTRUSIVE_NO_DANGLING + static const bstree_impl & container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return container_from_end_iterator(it.end_iterator_from_it()); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -2215,15 +2219,19 @@ class bstree inline void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/detail/workaround.hpp b/include/boost/intrusive/detail/workaround.hpp index f925a87a..3c808308 100644 --- a/include/boost/intrusive/detail/workaround.hpp +++ b/include/boost/intrusive/detail/workaround.hpp @@ -110,6 +110,16 @@ template struct static_assert_test {}; (unsigned)sizeof(::boost::intrusive::detail::STATIC_ASSERTION_FAILURE)>\ BOOST_JOIN(boost_intrusive_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +#endif //BOOST_NO_CXX11_STATIC_ASSERT + + +//GCC has some false positives with some functions returning references. +//This silences this warning in selected functions +#if defined(BOOST_GCC) && (BOOST_GCC >= 140000) +# define BOOST_INTRUSIVE_NO_DANGLING [[gnu::no_dangling]] +#else +# define BOOST_INTRUSIVE_NO_DANGLING #endif + #endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index 9871d973..507e73c6 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -500,6 +500,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. + BOOST_INTRUSIVE_NO_DANGLING inline static list_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return list_impl::priv_container_from_end_iterator(end_iterator); } @@ -511,6 +512,7 @@ class list_impl //! Throws: Nothing. //! //! Complexity: Constant. + BOOST_INTRUSIVE_NO_DANGLING inline static const list_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return list_impl::priv_container_from_end_iterator(end_iterator); } @@ -1391,6 +1393,7 @@ class list_impl /// @cond private: + BOOST_INTRUSIVE_NO_DANGLING static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) BOOST_NOEXCEPT { BOOST_INTRUSIVE_STATIC_ASSERT((has_container_from_iterator)); @@ -1501,9 +1504,11 @@ class list inline void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static list &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const list &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } }; diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index 04fce1ee..4ca437fe 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -567,15 +567,19 @@ class rbtree inline void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static rbtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const rbtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static rbtree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const rbtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index 2a5859c0..91d54c4c 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -554,15 +554,19 @@ class set inline void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -1049,15 +1053,19 @@ class multiset inline void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index ed0af556..01cac5f5 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -563,15 +563,19 @@ class sg_set inline void clone_from(BOOST_RV_REF(sg_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static sg_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const sg_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static sg_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const sg_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -1070,15 +1074,19 @@ class sg_multiset inline void clone_from(BOOST_RV_REF(sg_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static sg_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const sg_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static sg_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const sg_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index aaee1651..fa4d914e 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -1049,15 +1049,19 @@ class sgtree inline void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static sgtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const sgtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static sgtree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const sgtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index f39e7dfc..ac42cb48 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -660,6 +660,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. + BOOST_INTRUSIVE_NO_DANGLING inline static slist_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return slist_impl::priv_container_from_end_iterator(end_iterator); } @@ -671,6 +672,7 @@ class slist_impl //! Throws: Nothing. //! //! Complexity: Constant. + BOOST_INTRUSIVE_NO_DANGLING inline static const slist_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return slist_impl::priv_container_from_end_iterator(end_iterator); } @@ -2107,6 +2109,7 @@ class slist_impl static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_) { node_algorithms::swap_trailing_nodes(this_node, other_node); } + BOOST_INTRUSIVE_NO_DANGLING static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { //Obtaining the container from the end iterator is not possible with linear @@ -2229,9 +2232,11 @@ class slist inline void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static slist &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const slist &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } }; diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index f11424ac..a3df8a3e 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -575,15 +575,19 @@ class splay_set inline void clone_from(BOOST_RV_REF(splay_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static splay_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const splay_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static splay_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const splay_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -1086,15 +1090,19 @@ class splay_multiset inline void clone_from(BOOST_RV_REF(splay_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static splay_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const splay_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static splay_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const splay_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index e25647c6..919f70bd 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -642,15 +642,19 @@ class splaytree inline void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static splaytree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const splaytree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static splaytree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const splaytree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index 4d8c9161..c39ccfeb 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -1347,15 +1347,19 @@ class treap inline void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static treap &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const treap &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static treap &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const treap &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index f6a7a8fe..a2f47378 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -574,15 +574,19 @@ class treap_set inline void clone_from(BOOST_RV_REF(treap_set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static treap_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const treap_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static treap_set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const treap_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } }; @@ -1089,15 +1093,19 @@ class treap_multiset inline void clone_from(BOOST_RV_REF(treap_multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + BOOST_INTRUSIVE_NO_DANGLING inline static treap_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const treap_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast(Base::container_from_end_iterator(end_iterator)); } + BOOST_INTRUSIVE_NO_DANGLING inline static treap_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } + BOOST_INTRUSIVE_NO_DANGLING inline static const treap_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast(Base::container_from_iterator(it)); } };