diff options
Diffstat (limited to 'boost/intrusive/detail')
49 files changed, 1122 insertions, 683 deletions
diff --git a/boost/intrusive/detail/algo_type.hpp b/boost/intrusive/detail/algo_type.hpp index e40cb43b4e..6da48e9e79 100644 --- a/boost/intrusive/detail/algo_type.hpp +++ b/boost/intrusive/detail/algo_type.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP #define BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/algorithm.hpp b/boost/intrusive/detail/algorithm.hpp new file mode 100644 index 0000000000..d2421ffaad --- /dev/null +++ b/boost/intrusive/detail/algorithm.hpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/intrusive for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP +#define BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +struct algo_pred_equal +{ + template<class T> + bool operator()(const T &x, const T &y) const + { return x == y; } +}; + +struct algo_pred_less +{ + template<class T> + bool operator()(const T &x, const T &y) const + { return x < y; } +}; + +template<class InputIt1, class InputIt2, class BinaryPredicate> +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p) +{ + for (; first1 != last1; ++first1, ++first2) { + if (!p(*first1, *first2)) { + return false; + } + } + return true; +} + +template<class InputIt1, class InputIt2> +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) +{ return (algo_equal)(first1, last1, first2, algo_pred_equal()); } + +template<class InputIt1, class InputIt2, class BinaryPredicate> +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate pred) +{ + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + if (!pred(*first1, *first2)) + return false; + return first1 == last1 && first2 == last2; +} + +template<class InputIt1, class InputIt2> +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) +{ return (algo_equal)(first1, last1, first2, last2, algo_pred_equal()); } + +template <class InputIterator1, class InputIterator2, class BinaryPredicate> + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred) +{ + while (first1 != last1){ + if (first2 == last2 || *first2 < *first1) return false; + else if (pred(*first1, *first2)) return true; + ++first1; ++first2; + } + return (first2 != last2); +} + +template <class InputIterator1, class InputIterator2> + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) +{ return (algo_lexicographical_compare)(first1, last1, first2, last2, algo_pred_less()); } + +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP diff --git a/boost/intrusive/detail/any_node_and_algorithms.hpp b/boost/intrusive/detail/any_node_and_algorithms.hpp index 5a0e8c27fe..3c76e58528 100644 --- a/boost/intrusive/detail/any_node_and_algorithms.hpp +++ b/boost/intrusive/detail/any_node_and_algorithms.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_ANY_NODE_HPP #define BOOST_INTRUSIVE_ANY_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -43,13 +47,13 @@ struct any_list_node_traits typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; - static const node_ptr &get_next(const const_node_ptr & n) + static node_ptr get_next(const const_node_ptr & n) { return n->node_ptr_1; } static void set_next(const node_ptr & n, const node_ptr & next) { n->node_ptr_1 = next; } - static const node_ptr &get_previous(const const_node_ptr & n) + static node_ptr get_previous(const const_node_ptr & n) { return n->node_ptr_2; } static void set_previous(const node_ptr & n, const node_ptr & prev) @@ -64,7 +68,7 @@ struct any_slist_node_traits typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; - static const node_ptr &get_next(const const_node_ptr & n) + static node_ptr get_next(const const_node_ptr & n) { return n->node_ptr_1; } static void set_next(const node_ptr & n, const node_ptr & next) @@ -84,7 +88,7 @@ struct any_unordered_node_traits static const bool store_hash = true; static const bool optimize_multikey = true; - static const node_ptr &get_next(const const_node_ptr & n) + static node_ptr get_next(const const_node_ptr & n) { return n->node_ptr_1; } static void set_next(const node_ptr & n, const node_ptr & next) @@ -113,19 +117,19 @@ struct any_rbtree_node_traits typedef std::size_t color; - static const node_ptr &get_parent(const const_node_ptr & n) + static node_ptr get_parent(const const_node_ptr & n) { return n->node_ptr_1; } static void set_parent(const node_ptr & n, const node_ptr & p) { n->node_ptr_1 = p; } - static const node_ptr &get_left(const const_node_ptr & n) + static node_ptr get_left(const const_node_ptr & n) { return n->node_ptr_2; } static void set_left(const node_ptr & n, const node_ptr & l) { n->node_ptr_2 = l; } - static const node_ptr &get_right(const const_node_ptr & n) + static node_ptr get_right(const const_node_ptr & n) { return n->node_ptr_3; } static void set_right(const node_ptr & n, const node_ptr & r) @@ -154,19 +158,19 @@ struct any_avltree_node_traits typedef std::size_t balance; - static const node_ptr &get_parent(const const_node_ptr & n) + static node_ptr get_parent(const const_node_ptr & n) { return n->node_ptr_1; } static void set_parent(const node_ptr & n, const node_ptr & p) { n->node_ptr_1 = p; } - static const node_ptr &get_left(const const_node_ptr & n) + static node_ptr get_left(const const_node_ptr & n) { return n->node_ptr_2; } static void set_left(const node_ptr & n, const node_ptr & l) { n->node_ptr_2 = l; } - static const node_ptr &get_right(const const_node_ptr & n) + static node_ptr get_right(const const_node_ptr & n) { return n->node_ptr_3; } static void set_right(const node_ptr & n, const node_ptr & r) @@ -196,19 +200,19 @@ struct any_tree_node_traits typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; - static const node_ptr &get_parent(const const_node_ptr & n) + static node_ptr get_parent(const const_node_ptr & n) { return n->node_ptr_1; } static void set_parent(const node_ptr & n, const node_ptr & p) { n->node_ptr_1 = p; } - static const node_ptr &get_left(const const_node_ptr & n) + static node_ptr get_left(const const_node_ptr & n) { return n->node_ptr_2; } static void set_left(const node_ptr & n, const node_ptr & l) { n->node_ptr_2 = l; } - static const node_ptr &get_right(const const_node_ptr & n) + static node_ptr get_right(const const_node_ptr & n) { return n->node_ptr_3; } static void set_right(const node_ptr & n, const node_ptr & r) diff --git a/boost/intrusive/detail/array_initializer.hpp b/boost/intrusive/detail/array_initializer.hpp index b2072a872d..126a253afb 100644 --- a/boost/intrusive/detail/array_initializer.hpp +++ b/boost/intrusive/detail/array_initializer.hpp @@ -13,10 +13,15 @@ #ifndef BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP #define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif +#include <boost/config.hpp> #include <boost/core/no_exceptions_support.hpp> namespace boost { @@ -31,7 +36,7 @@ union max_align int int_; long long_; #ifdef BOOST_HAS_LONG_LONG - long long long_long_; + ::boost::long_long_type long_long_; #endif float float_; double double_; diff --git a/boost/intrusive/detail/assert.hpp b/boost/intrusive/detail/assert.hpp index d75d225ac4..7199eb240c 100644 --- a/boost/intrusive/detail/assert.hpp +++ b/boost/intrusive/detail/assert.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP #define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) #pragma once #endif diff --git a/boost/intrusive/detail/avltree_node.hpp b/boost/intrusive/detail/avltree_node.hpp index 522806a89e..22b8fd1219 100644 --- a/boost/intrusive/detail/avltree_node.hpp +++ b/boost/intrusive/detail/avltree_node.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_AVLTREE_NODE_HPP #define BOOST_INTRUSIVE_AVLTREE_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/bstree_algorithms_base.hpp b/boost/intrusive/detail/bstree_algorithms_base.hpp new file mode 100644 index 0000000000..ed28a430ea --- /dev/null +++ b/boost/intrusive/detail/bstree_algorithms_base.hpp @@ -0,0 +1,184 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP +#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <boost/intrusive/detail/uncast.hpp> + +namespace boost { +namespace intrusive { + +template<class NodeTraits> +class bstree_algorithms_base +{ + public: + typedef typename NodeTraits::node node; + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + + //! <b>Requires</b>: 'node' is a node from the tree except the header. + //! + //! <b>Effects</b>: Returns the next node of the tree. + //! + //! <b>Complexity</b>: Average constant time. + //! + //! <b>Throws</b>: Nothing. + static node_ptr next_node(const node_ptr & node) + { + node_ptr const n_right(NodeTraits::get_right(node)); + if(n_right){ + return minimum(n_right); + } + else { + node_ptr n(node); + node_ptr p(NodeTraits::get_parent(n)); + while(n == NodeTraits::get_right(p)){ + n = p; + p = NodeTraits::get_parent(p); + } + return NodeTraits::get_right(n) != p ? p : n; + } + } + + //! <b>Requires</b>: 'node' is a node from the tree except the leftmost node. + //! + //! <b>Effects</b>: Returns the previous node of the tree. + //! + //! <b>Complexity</b>: Average constant time. + //! + //! <b>Throws</b>: Nothing. + static node_ptr prev_node(const node_ptr & node) + { + if(is_header(node)){ + return NodeTraits::get_right(node); + //return maximum(NodeTraits::get_parent(node)); + } + else if(NodeTraits::get_left(node)){ + return maximum(NodeTraits::get_left(node)); + } + else { + node_ptr p(node); + node_ptr x = NodeTraits::get_parent(p); + while(p == NodeTraits::get_left(x)){ + p = x; + x = NodeTraits::get_parent(x); + } + return x; + } + } + + //! <b>Requires</b>: 'node' is a node of a tree but not the header. + //! + //! <b>Effects</b>: Returns the minimum node of the subtree starting at p. + //! + //! <b>Complexity</b>: Logarithmic to the size of the subtree. + //! + //! <b>Throws</b>: Nothing. + static node_ptr minimum(node_ptr node) + { + for(node_ptr p_left = NodeTraits::get_left(node) + ;p_left + ;p_left = NodeTraits::get_left(node)){ + node = p_left; + } + return node; + } + + //! <b>Requires</b>: 'node' is a node of a tree but not the header. + //! + //! <b>Effects</b>: Returns the maximum node of the subtree starting at p. + //! + //! <b>Complexity</b>: Logarithmic to the size of the subtree. + //! + //! <b>Throws</b>: Nothing. + static node_ptr maximum(node_ptr node) + { + for(node_ptr p_right = NodeTraits::get_right(node) + ;p_right + ;p_right = NodeTraits::get_right(node)){ + node = p_right; + } + return node; + } + + //! <b>Requires</b>: p is a node of a tree. + //! + //! <b>Effects</b>: Returns true if p is the header of the tree. + //! + //! <b>Complexity</b>: Constant. + //! + //! <b>Throws</b>: Nothing. + static bool is_header(const const_node_ptr & p) + { + node_ptr p_left (NodeTraits::get_left(p)); + node_ptr p_right(NodeTraits::get_right(p)); + if(!NodeTraits::get_parent(p) || //Header condition when empty tree + (p_left && p_right && //Header always has leftmost and rightmost + (p_left == p_right || //Header condition when only node + (NodeTraits::get_parent(p_left) != p || + NodeTraits::get_parent(p_right) != p )) + //When tree size > 1 headers can't be leftmost's + //and rightmost's parent + )){ + return true; + } + return false; + } + + //! <b>Requires</b>: 'node' is a node of the tree or a header node. + //! + //! <b>Effects</b>: Returns the header of the tree. + //! + //! <b>Complexity</b>: Logarithmic. + //! + //! <b>Throws</b>: Nothing. + static node_ptr get_header(const const_node_ptr & node) + { + node_ptr n(detail::uncast(node)); + node_ptr p(NodeTraits::get_parent(node)); + //If p is null, then n is the header of an empty tree + if(p){ + //Non-empty tree, check if n is neither root nor header + node_ptr pp(NodeTraits::get_parent(p)); + //If granparent is not equal to n, then n is neither root nor header, + //the try the fast path + if(n != pp){ + do{ + n = p; + p = pp; + pp = NodeTraits::get_parent(pp); + }while(n != pp); + n = p; + } + //Check if n is root or header when size() > 0 + else if(!bstree_algorithms_base::is_header(n)){ + n = p; + } + } + return n; + } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP diff --git a/boost/intrusive/detail/common_slist_algorithms.hpp b/boost/intrusive/detail/common_slist_algorithms.hpp index 4c7f1a11e0..deaea7c97b 100644 --- a/boost/intrusive/detail/common_slist_algorithms.hpp +++ b/boost/intrusive/detail/common_slist_algorithms.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP #define BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -143,7 +147,7 @@ class common_slist_algorithms } BOOST_CATCH(...){ node_traits::set_next(last_to_remove, new_f); - throw; + BOOST_RETHROW; } BOOST_CATCH_END node_traits::set_next(last_to_remove, new_f); diff --git a/boost/intrusive/detail/default_header_holder.hpp b/boost/intrusive/detail/default_header_holder.hpp index c471691640..d10109b8c9 100644 --- a/boost/intrusive/detail/default_header_holder.hpp +++ b/boost/intrusive/detail/default_header_holder.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP #define BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -28,34 +32,34 @@ namespace detail { template < typename NodeTraits > struct default_header_holder : public NodeTraits::node { - typedef NodeTraits node_traits; - typedef typename node_traits::node node; - typedef typename node_traits::node_ptr node_ptr; - typedef typename node_traits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; - default_header_holder() : node() {} + default_header_holder() : node() {} - const_node_ptr get_node() const - { return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); } + const_node_ptr get_node() const + { return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); } - node_ptr get_node() - { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } + node_ptr get_node() + { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } - // (unsafe) downcast used to implement container-from-iterator - static default_header_holder* get_holder(const node_ptr &p) - { return static_cast< default_header_holder* >(boost::intrusive::detail::to_raw_pointer(p)); } + // (unsafe) downcast used to implement container-from-iterator + static default_header_holder* get_holder(const node_ptr &p) + { return static_cast< default_header_holder* >(boost::intrusive::detail::to_raw_pointer(p)); } }; // type function producing the header node holder template < typename Value_Traits, typename HeaderHolder > struct get_header_holder_type { - typedef HeaderHolder type; + typedef HeaderHolder type; }; template < typename Value_Traits > struct get_header_holder_type< Value_Traits, void > { - typedef default_header_holder< typename Value_Traits::node_traits > type; + typedef default_header_holder< typename Value_Traits::node_traits > type; }; } //namespace detail diff --git a/boost/intrusive/detail/ebo_functor_holder.hpp b/boost/intrusive/detail/ebo_functor_holder.hpp index d2e8107b67..e8e73ff62a 100644 --- a/boost/intrusive/detail/ebo_functor_holder.hpp +++ b/boost/intrusive/detail/ebo_functor_holder.hpp @@ -14,11 +14,13 @@ #ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP #define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP -#if defined(_MSC_VER) -# pragma once +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> #endif -#include <boost/config.hpp> +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif namespace boost { namespace intrusive { @@ -181,7 +183,7 @@ class ebo_functor_holder_impl<T, false> public: ebo_functor_holder_impl() {} - ebo_functor_holder_impl(const T& t) + explicit ebo_functor_holder_impl(const T& t) : T(t) {} template<class Arg1, class Arg2> @@ -202,7 +204,7 @@ class ebo_functor_holder public: ebo_functor_holder(){} - ebo_functor_holder(const T& t) + explicit ebo_functor_holder(const T& t) : super(t) {} diff --git a/boost/intrusive/detail/empty_node_checker.hpp b/boost/intrusive/detail/empty_node_checker.hpp index 33d78a34ba..16aa5600e7 100644 --- a/boost/intrusive/detail/empty_node_checker.hpp +++ b/boost/intrusive/detail/empty_node_checker.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP #define BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/equal_to_value.hpp b/boost/intrusive/detail/equal_to_value.hpp index 3ffd1c26cf..c341f488e9 100644 --- a/boost/intrusive/detail/equal_to_value.hpp +++ b/boost/intrusive/detail/equal_to_value.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP #define BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/exception_disposer.hpp b/boost/intrusive/detail/exception_disposer.hpp index 1226f5e525..a10d63a75d 100644 --- a/boost/intrusive/detail/exception_disposer.hpp +++ b/boost/intrusive/detail/exception_disposer.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP #define BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/function_detector.hpp b/boost/intrusive/detail/function_detector.hpp index f72865df9b..5ecaeaf073 100644 --- a/boost/intrusive/detail/function_detector.hpp +++ b/boost/intrusive/detail/function_detector.hpp @@ -22,7 +22,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP #define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/generic_hook.hpp b/boost/intrusive/detail/generic_hook.hpp index c5af081d65..b57a12b458 100644 --- a/boost/intrusive/detail/generic_hook.hpp +++ b/boost/intrusive/detail/generic_hook.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP #define BOOST_INTRUSIVE_GENERIC_HOOK_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -134,13 +138,13 @@ class generic_hook , typename NodeAlgorithms::node , node_holder<typename NodeAlgorithms::node, Tag, BaseHookType> >::type - //If this is the a default-tagged base hook derive from a class that + //If this is the a default-tagged base hook derive from a class that //will define an special internal typedef. Containers will be able to detect this //special typedef and obtain generic_hook's internal types in order to deduce //value_traits for this hook. , public hook_tags_definer < generic_hook<NodeAlgorithms, Tag, LinkMode, BaseHookType> - , detail::is_same<Tag, default_tag>::value*BaseHookType> + , detail::is_same<Tag, dft_tag>::value*BaseHookType> /// @endcond { /// @cond diff --git a/boost/intrusive/detail/get_value_traits.hpp b/boost/intrusive/detail/get_value_traits.hpp index 6f5a9e3f04..686e059583 100644 --- a/boost/intrusive/detail/get_value_traits.hpp +++ b/boost/intrusive/detail/get_value_traits.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP #define BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/has_member_function_callable_with.hpp b/boost/intrusive/detail/has_member_function_callable_with.hpp index ca96f15a19..30bef56c2b 100644 --- a/boost/intrusive/detail/has_member_function_callable_with.hpp +++ b/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -1,372 +1,331 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2014. Distributed under the Boost +// (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/intrusive for documentation. +// See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// -// sample.h +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP -#if !defined(BOOST_PP_IS_ITERATING) +//Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and +//wrong SFINAE for GCC 4.2/4.3 +#if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430) + #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +#elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200 ) + #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +#endif +#include <cstddef> +#include <boost/move/utility_core.hpp> +#include <boost/move/detail/fwd_macros.hpp> - #ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED - #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED +namespace boost_intrusive_hmfcw { - #include <boost/intrusive/detail/preprocessor.hpp> - #include <boost/intrusive/detail/mpl.hpp> - #include <boost/move/utility_core.hpp> +typedef char yes_type; +struct no_type{ char dummy[2]; }; +#if defined(BOOST_NO_CXX11_DECLTYPE) - //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and - //wrong SFINAE for GCC 4.2/4.3 - #if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430) - #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED - #elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200 ) - #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED - #endif +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - namespace boost_intrusive_has_member_function_callable_with { +template<class T> +struct make_dontcare +{ + typedef dont_care type; +}; - struct dont_care - { - dont_care(...); - }; +#endif - template<class T> - struct make_dontcare - { - typedef boost_intrusive_has_member_function_callable_with::dont_care type; - }; +struct dont_care +{ + dont_care(...); +}; - struct private_type - { - static private_type p; - private_type const &operator,(int) const; - }; +struct private_type +{ + static private_type p; + private_type const &operator,(int) const; +}; - typedef char yes_type; // sizeof(yes_type) == 1 - struct no_type{ char dummy[2]; }; // sizeof(no_type) == 2 +template<typename T> +no_type is_private_type(T const &); +yes_type is_private_type(private_type const &); - template<typename T> - no_type is_private_type(T const &); - yes_type is_private_type(private_type const &); +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) - } //boost_intrusive_has_member_function_callable_with +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_SINGLE_ITERATION - #endif +template<typename T> struct remove_cv { typedef T type; }; +template<typename T> struct remove_cv<const T> { typedef T type; }; +template<typename T> struct remove_cv<const volatile T> { typedef T type; }; +template<typename T> struct remove_cv<volatile T> { typedef T type; }; + +#endif + +} //namespace boost_intrusive_hmfcw { + +#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!" +#endif - #endif //BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!" +#endif -#else //!BOOST_PP_IS_ITERATING +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!" +#endif - #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME - #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME not defined!" - #endif +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF +#else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF , +#endif - #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN - #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN not defined!" - #endif +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!" +#endif - #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" - #endif +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) + //With decltype and variadic templaes, things are pretty easy + template<typename Fun, class ...Args> + struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template<class U> + static decltype(boost::move_detail::declval<U>(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...) + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + template<class U> + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + +#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX + // declaration, special case and 0 arg specializaton + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// - #if BOOST_PP_ITERATION_START() > BOOST_PP_ITERATION_FINISH() - #error "BOOST_PP_ITERATION_START() must be <= BOOST_PP_ITERATION_FINISH()" - #endif + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX for 1 to N arguments + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //defined(BOOST_NO_CXX11_DECLTYPE) must be true + template<class Fun, class ...DontCares> + struct FunWrapTmpl : Fun + { + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const; + }; - #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START() + template<typename Fun, class ...Args> + struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, Args...> + { + typedef FunWrapTmpl<typename boost_intrusive_hmfcw::make_dontcare<Args>::type...> FunWrap; + + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == + sizeof(boost_intrusive_hmfcw::is_private_type + ( (::boost::move_detail::declval< FunWrap<Fun> >(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...), 0) ) + ) + ); + }; + #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN + //Preprocessor must be used to generate specializations instead of variadic templates template <typename Type> - class BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) { struct BaseMixin { void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(); }; - struct Base : public ::boost::intrusive::detail::remove_cv<Type>::type, public BaseMixin { Base(); }; + struct Base : public boost_intrusive_hmfcw::remove_cv<Type>::type, public BaseMixin {}; template <typename T, T t> class Helper{}; template <typename U> - static boost_intrusive_has_member_function_callable_with::no_type deduce + static boost_intrusive_hmfcw::no_type deduce (U*, Helper<void (BaseMixin::*)(), &U::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME>* = 0); - static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); + static boost_intrusive_hmfcw::yes_type deduce(...); public: - static const bool value = - sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); + static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); }; - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - template<typename Fun, bool HasFunc - BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION_FINISH(), BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT, _)> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl); - //! - - template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), class P)> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) - <Fun, false BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P)> - { - static const bool value = false; - }; - //! - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - template<typename Fun, bool HasFunc, class ...Args> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl); - - template<typename Fun, class ...Args> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - <Fun, false, Args...> - { - static const bool value = false; - }; - - #ifdef BOOST_NO_CXX11_DECLTYPE - - //Special case for 0 args - template< class F - , std::size_t N = - sizeof((boost::move_detail::declval<F>(). - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))> - struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - { - boost_intrusive_has_member_function_callable_with::yes_type dummy; - BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); - }; - - //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not - //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. - template<class F> - struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0> - { - boost_intrusive_has_member_function_callable_with::no_type dummy; - BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); - }; - - #endif //#ifdef BOOST_NO_CXX11_DECLTYPE - - template<typename Fun> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - <Fun, true> - { - #ifndef BOOST_NO_CXX11_DECLTYPE - template<class U, class V = decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()) > - static boost_intrusive_has_member_function_callable_with::yes_type Test(U*); - #else - template<class U> - static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - <U> Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*); - #endif - - template <class U> - static boost_intrusive_has_member_function_callable_with::no_type Test(...); - - static const bool value = sizeof(Test< Fun >(0)) - == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); - }; - - template<typename Fun, class ...Args> - struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) - <Fun, true , Args...> - { - - template<class ...DontCares> - struct FunWrapTmpl : Fun - { - FunWrapTmpl(); - using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; - - boost_intrusive_has_member_function_callable_with::private_type - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME - ( DontCares...) const; - }; - - typedef FunWrapTmpl<typename boost_intrusive_has_member_function_callable_with::make_dontcare<Args>::type...> FunWrap; - - static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == - sizeof(boost_intrusive_has_member_function_callable_with::is_private_type - ( (::boost::move_detail::declval< FunWrap >(). - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME - ( ::boost::move_detail::declval<Args>()... ), 0) ) - ) - ); - }; + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX specializations + // + ///////////////////////////////////////////////////////// - template<typename Fun, class ...Args> - struct BOOST_PP_CAT( has_member_function_callable_with_ - , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - : public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_ - , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - < Fun - , BOOST_PP_CAT( has_member_function_named_ - , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )<Fun>::value - , Args... > - {}; + template<typename Fun, bool HasFunc BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); - #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END - - #endif //BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START() - - #if BOOST_PP_ITERATION() == 0 - - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN - - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if !defined(_MSC_VER) || (_MSC_VER < 1600) - - #if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) - - template<typename Fun> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)> - { - //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and - //wrong SFINAE for GCC 4.2/4.3 - static const bool value = true; - }; - - #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) - - //Special case for 0 args - template< class F - , std::size_t N = - sizeof((boost::move_detail::declval<F>(). - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))> - struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - { - boost_intrusive_has_member_function_callable_with::yes_type dummy; - BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); - }; - - //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not - //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. - template<class F> - struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0> - { - boost_intrusive_has_member_function_callable_with::no_type dummy; - BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); - }; - - template<typename Fun> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)> - { - template<class U> - static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U> - Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*); - - template <class U> - static boost_intrusive_has_member_function_callable_with::no_type Test(...); + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASS,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + <Fun, false BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + { + static const bool value = false; + }; - static const bool value = sizeof(Test< Fun >(0)) - == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); - }; - #endif //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + //0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + #if !defined(BOOST_NO_CXX11_DECLTYPE) - #else //#if !defined(_MSC_VER) || (_MSC_VER < 1600) template<typename Fun> - struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)> + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true> { template<class U> - static decltype( boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() - , boost_intrusive_has_member_function_callable_with::yes_type()) - Test(U*); + static decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + , boost_intrusive_hmfcw::yes_type()) Test(U* f); template<class U> - static boost_intrusive_has_member_function_callable_with::no_type Test(...); - - static const bool value = sizeof(Test<Fun>(0)) - == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); }; - #endif //#if !defined(_MSC_VER) || (_MSC_VER < 1600) - - #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #endif //#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #else //defined(BOOST_NO_CXX11_DECLTYPE) - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) - #else //BOOST_PP_ITERATION() == 0 + template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> + struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN - - template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class P)> - struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_ - , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) - <Fun, true - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), P) - BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()) - , BOOST_INTRUSIVE_PP_IDENTITY - , void)> - { - struct FunWrap : Fun + template<typename Fun> + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true> { - FunWrap(); - - using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; - boost_intrusive_has_member_function_callable_with::private_type - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME - ( BOOST_PP_ENUM(BOOST_PP_ITERATION() - , BOOST_INTRUSIVE_PP_IDENTITY - , boost_intrusive_has_member_function_callable_with::dont_care)) const; + template<class U> static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U> + Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*); + template<class U> static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); }; - static bool const value = - (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == - sizeof(boost_intrusive_has_member_function_callable_with::is_private_type - ( (boost::move_detail::declval<FunWrap>(). - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME - ( BOOST_PP_ENUM( BOOST_PP_ITERATION(), BOOST_INTRUSIVE_PP_DECLVAL, _) ), 0 - ) - ) - ) - ); - }; - - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END - #endif //#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #endif //BOOST_PP_ITERATION() == 0 - - #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH() - - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN - - template<typename Fun - BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION_FINISH(), BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT, _)> - struct BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - : public BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) - <Fun, BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P) > - {}; - - BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END - - #endif //#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME - #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN - #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END - - #endif //#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH() + #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) -#endif //!BOOST_PP_IS_ITERATING + template<typename Fun> + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true> + {//GCC [3.4-4.3) gives ICE when instantiating the 0 arg version so it is not supported. + static const bool value = true; + }; + + #endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + #endif //!defined(BOOST_NO_CXX11_DECLTYPE) + #endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + //1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + #if defined(BOOST_NO_CXX11_DECLTYPE) + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + template<class Fun> struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) : Fun\ + {\ + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\ + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\ + (BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\ + };\ + \ + template<typename Fun, BOOST_MOVE_CLASS##N>\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true, BOOST_MOVE_TARG##N>\ + {\ + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\ + ( (::boost::move_detail::declval\ + < BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun> >().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\ + )\ + );\ + };\ + // + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + template<typename Fun, BOOST_MOVE_CLASS##N>\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + <Fun, true, BOOST_MOVE_TARG##N>\ + {\ + template<class U>\ + static decltype(boost::move_detail::declval<U>().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\ + , boost_intrusive_hmfcw::yes_type()) Test(U* f);\ + template<class U>\ + static boost_intrusive_hmfcw::no_type Test(...);\ + static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\ + };\ + // + #endif + //////////////////////////////////// + // Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1 + //////////////////////////////////// + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1 + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #endif + BOOST_MOVE_CAT + (BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO) + ,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX) + (BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION) + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN + //////////////////////////////////// + // End of BOOST_MOVE_ITERATE_NTOM + //////////////////////////////////// + #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_FUNC + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //Otherwise use the preprocessor + template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + <Fun + , BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + {}; + #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + +//Undef local macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF + +//Undef user defined macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END diff --git a/boost/intrusive/detail/hashtable_node.hpp b/boost/intrusive/detail/hashtable_node.hpp index 6449fa0dd2..923a3e1d38 100644 --- a/boost/intrusive/detail/hashtable_node.hpp +++ b/boost/intrusive/detail/hashtable_node.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_HASHTABLE_NODE_HPP #define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/hook_traits.hpp b/boost/intrusive/detail/hook_traits.hpp index c9c115b1de..71f342af06 100644 --- a/boost/intrusive/detail/hook_traits.hpp +++ b/boost/intrusive/detail/hook_traits.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP #define BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/iiterator.hpp b/boost/intrusive/detail/iiterator.hpp index 8378ead6ad..5c6721bd0e 100644 --- a/boost/intrusive/detail/iiterator.hpp +++ b/boost/intrusive/detail/iiterator.hpp @@ -13,71 +13,32 @@ #ifndef BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP #define BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif +#include <boost/intrusive/detail/iterator.hpp> #include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/is_stateful_value_traits.hpp> -#include <boost/intrusive/detail/std_fwd.hpp> - -#include <cstddef> - namespace boost { namespace intrusive { -template<class Category, class T, class Distance, class Pointer, class Reference> -struct iterator -{ - typedef Category iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef Pointer pointer; - typedef Reference reference; -}; - -template<class Iterator> -struct iterator_traits -{ - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; - typedef typename Iterator::iterator_category iterator_category; -}; - -template<class T> -struct iterator_traits<T*> -{ - typedef std::ptrdiff_t difference_type; - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef std::random_access_iterator_tag iterator_category; -}; - -template<class T> -struct iterator_traits<const T*> -{ - typedef std::ptrdiff_t difference_type; - typedef T value_type; - typedef const T* pointer; - typedef const T& reference; - typedef std::random_access_iterator_tag iterator_category; -}; - template<class ValueTraits> struct value_traits_pointers { typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT (boost::intrusive::detail:: , ValueTraits, value_traits_ptr - , typename pointer_traits<typename ValueTraits::node_traits::node_ptr>::template + , typename boost::intrusive::pointer_traits<typename ValueTraits::node_traits::node_ptr>::template rebind_pointer<ValueTraits>::type) value_traits_ptr; - typedef typename pointer_traits<value_traits_ptr>::template + typedef typename boost::intrusive::pointer_traits<value_traits_ptr>::template rebind_pointer<ValueTraits const>::type const_value_traits_ptr; }; @@ -154,73 +115,6 @@ struct iiterator_members<NodePtr, StoredPointer, false> NodePtr nodeptr_; }; -namespace detail { - -template<class InputIt, class Distance> inline -void advance_impl(InputIt& it, Distance n, const std::input_iterator_tag&) -{ - while(n--) - ++it; -} - -template<class InputIt, class Distance> inline -void advance_impl(InputIt& it, Distance n, std::forward_iterator_tag &) -{ - while(n--) - ++it; -} - -template<class InputIt, class Distance> inline -void advance_impl(InputIt& it, Distance n, std::bidirectional_iterator_tag &) -{ - for (; 0 < n; --n) - ++it; - for (; n < 0; ++n) - --it; -} - -template<class InputIt, class Distance> -inline void advance_impl(InputIt& it, Distance n, const std::random_access_iterator_tag &) -{ - it += n; -} - -} //namespace detail - -template<class InputIt, class Distance> -inline void iterator_advance(InputIt& it, Distance n) -{ // increment iterator by offset, arbitrary iterators - boost::intrusive::detail::advance_impl(it, n, boost::intrusive::iterator_traits<InputIt>::iterator_category()); -} - -namespace detail{ - -template<class InputIt, class Distance, class Category> -inline void distance_impl(InputIt first, InputIt last, Distance& off, const Category &) -{ - while(first != last){ - ++off; - ++first; - } -} - -template<class InputIt, class Distance> inline -void distance_impl(InputIt first, InputIt last, Distance& off, const std::random_access_iterator_tag&) -{ - off += last - first; -} - -} //namespace detail - -template<class InputIt> inline -typename iterator_traits<InputIt>::difference_type iterator_distance(InputIt first, InputIt last) -{ - typename iterator_traits<InputIt>::difference_type off = 0; - boost::intrusive::detail::distance_impl(first, last, off, boost::intrusive::iterator_traits<InputIt>::iterator_category()); - return off; -} - - } //namespace intrusive } //namespace boost diff --git a/boost/intrusive/detail/is_stateful_value_traits.hpp b/boost/intrusive/detail/is_stateful_value_traits.hpp index da2260edf6..680b043aa8 100644 --- a/boost/intrusive/detail/is_stateful_value_traits.hpp +++ b/boost/intrusive/detail/is_stateful_value_traits.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP #define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/iterator.hpp b/boost/intrusive/detail/iterator.hpp new file mode 100644 index 0000000000..fb6fb81976 --- /dev/null +++ b/boost/intrusive/detail/iterator.hpp @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <cstddef> +#include <boost/intrusive/detail/std_fwd.hpp> +#include <boost/move/detail/iterator_traits.hpp> +#include <boost/move/detail/meta_utils_core.hpp> + +namespace boost { +namespace intrusive { + +using boost::movelib::iterator_traits; + +//////////////////// +// iterator +//////////////////// +template<class Category, class T, class Distance, class Pointer = T*, class Reference = T&> +struct iterator +{ + typedef Category iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template<class I, class Tag, class R = void> +struct iterator_enable_if_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits<I>::iterator_category + , Tag + >::value + , R> +{}; + +template<class I, class Tag, class R = void> +struct iterator_disable_if_tag + : ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits<I>::iterator_category + , Tag + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag_difference_type +//////////////////////////////////////// +template<class I, class Tag> +struct iterator_enable_if_tag_difference_type + : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type> +{}; + +template<class I, class Tag> +struct iterator_disable_if_tag_difference_type + : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type> +{}; + +//////////////////// +// advance +//////////////////// +template<class InputIt, class Distance> inline +typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template<class InputIt, class Distance> inline +typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template<class InputIt, class Distance> inline +typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type + iterator_advance(InputIt& it, Distance n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +template<class InputIt, class Distance> inline +typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + +//////////////////// +// distance +//////////////////// +template<class InputIt> inline +typename iterator_disable_if_tag_difference_type + <InputIt, std::random_access_iterator_tag>::type + iterator_distance(InputIt first, InputIt last) +{ + typename iterator_traits<InputIt>::difference_type off = 0; + while(first != last){ + ++off; + ++first; + } + return off; +} + +template<class InputIt> inline +typename iterator_enable_if_tag_difference_type + <InputIt, std::random_access_iterator_tag>::type + iterator_distance(InputIt first, InputIt last) +{ + typename iterator_traits<InputIt>::difference_type off = last - first; + return off; +} + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP diff --git a/boost/intrusive/detail/key_nodeptr_comp.hpp b/boost/intrusive/detail/key_nodeptr_comp.hpp index dfee8b9bfc..8c456634e5 100644 --- a/boost/intrusive/detail/key_nodeptr_comp.hpp +++ b/boost/intrusive/detail/key_nodeptr_comp.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP #define BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -26,7 +30,8 @@ namespace detail { template<class KeyValueCompare, class ValueTraits> struct key_nodeptr_comp - : private ebo_functor_holder<KeyValueCompare> + //Use public inheritance to avoid MSVC bugs with closures + : public ebo_functor_holder<KeyValueCompare> { typedef ValueTraits value_traits; typedef typename value_traits::value_type value_type; @@ -44,6 +49,7 @@ struct key_nodeptr_comp static const bool value = is_same<T, const_node_ptr>::value || is_same<T, node_ptr>::value; }; + //key_forward template<class T> const value_type & key_forward (const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const @@ -53,14 +59,23 @@ struct key_nodeptr_comp const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const { return key; } + //operator() 1 arg + template<class KeyType> + bool operator()(const KeyType &key1) const + { return base_t::get()(this->key_forward(key1)); } + template<class KeyType> + bool operator()(const KeyType &key1) + { return base_t::get()(this->key_forward(key1)); } + + //operator() 2 arg template<class KeyType, class KeyType2> bool operator()(const KeyType &key1, const KeyType2 &key2) const { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); } - template<class KeyType> - bool operator()(const KeyType &key1) const - { return base_t::get()(this->key_forward(key1)); } + template<class KeyType, class KeyType2> + bool operator()(const KeyType &key1, const KeyType2 &key2) + { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); } const ValueTraits *const traits_; }; diff --git a/boost/intrusive/detail/list_iterator.hpp b/boost/intrusive/detail/list_iterator.hpp index efddfba3f1..77c9fa6097 100644 --- a/boost/intrusive/detail/list_iterator.hpp +++ b/boost/intrusive/detail/list_iterator.hpp @@ -14,7 +14,11 @@ #ifndef BOOST_INTRUSIVE_LIST_ITERATOR_HPP #define BOOST_INTRUSIVE_LIST_ITERATOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/list_node.hpp b/boost/intrusive/detail/list_node.hpp index ba97ece956..f740e545e8 100644 --- a/boost/intrusive/detail/list_node.hpp +++ b/boost/intrusive/detail/list_node.hpp @@ -14,7 +14,11 @@ #ifndef BOOST_INTRUSIVE_LIST_NODE_HPP #define BOOST_INTRUSIVE_LIST_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/math.hpp b/boost/intrusive/detail/math.hpp index f212ae743f..03000fceeb 100644 --- a/boost/intrusive/detail/math.hpp +++ b/boost/intrusive/detail/math.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_MATH_HPP #define BOOST_INTRUSIVE_DETAIL_MATH_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -84,9 +88,9 @@ namespace detail { #if defined(BOOST_HAS_LONG_LONG) template<> - struct builtin_clz_dispatch<unsigned long long> + struct builtin_clz_dispatch< ::boost::ulong_long_type > { - static unsigned long long call(unsigned long long n) + static ::boost::ulong_long_type call(::boost::ulong_long_type n) { return __builtin_clzll(n); } }; #endif @@ -154,7 +158,7 @@ namespace detail { inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 32>) { - static const int MultiplyDeBruijnBitPosition[32] = + static const int MultiplyDeBruijnBitPosition[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 diff --git a/boost/intrusive/detail/memory_util.hpp b/boost/intrusive/detail/memory_util.hpp deleted file mode 100644 index 18a5d3e7e2..0000000000 --- a/boost/intrusive/detail/memory_util.hpp +++ /dev/null @@ -1,92 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Pablo Halpern 2009. 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) -// -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2011-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_ALLOCATOR_MEMORY_UTIL_HPP -#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP - -#if defined(_MSC_VER) -# pragma once -#endif - -#include <boost/intrusive/detail/workaround.hpp> -#include <boost/intrusive/detail/mpl.hpp> -#include <boost/intrusive/detail/preprocessor.hpp> -#include <boost/preprocessor/iteration/iterate.hpp> - -namespace boost { -namespace intrusive { -namespace detail { - -template <typename T> -inline T* addressof(T& obj) -{ - return static_cast<T*> - (static_cast<void*> - (const_cast<char*> - (&reinterpret_cast<const char&>(obj)) - ) - ); -} - -template <typename T> -struct LowPriorityConversion -{ - // Convertible from T with user-defined-conversion rank. - LowPriorityConversion(const T&) { } -}; - -}}} //namespace boost::intrusive::detail - -#include <boost/intrusive/detail/has_member_function_callable_with.hpp> - -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} -#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>)) -#include BOOST_PP_ITERATE() - -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} -#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>)) -#include BOOST_PP_ITERATE() - -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} -#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>)) -#include BOOST_PP_ITERATE() - -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} -#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>)) -#include BOOST_PP_ITERATE() - -namespace boost { -namespace intrusive { -namespace detail { - -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type) -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr) - -} //namespace detail { -} //namespace intrusive { -} //namespace boost { - -#endif // ! defined(BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP) diff --git a/boost/intrusive/detail/minimal_less_equal_header.hpp b/boost/intrusive/detail/minimal_less_equal_header.hpp new file mode 100644 index 0000000000..5e8a19debf --- /dev/null +++ b/boost/intrusive/detail/minimal_less_equal_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015 +// +// 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_MINIMAL_LESS_EQUAL_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP +# +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#//Try to avoid including <functional>, as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include <bits/stl_function.h> +#else +# include <functional> //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP diff --git a/boost/intrusive/detail/minimal_pair_header.hpp b/boost/intrusive/detail/minimal_pair_header.hpp new file mode 100644 index 0000000000..1358a08588 --- /dev/null +++ b/boost/intrusive/detail/minimal_pair_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015 +// +// 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_MINIMAL_PAIR_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif +# +#//Try to avoid including <utility>, as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include <bits/stl_pair.h> +#else +# include <utility> //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP diff --git a/boost/intrusive/detail/mpl.hpp b/boost/intrusive/detail/mpl.hpp index 9b2c9f114c..39d2c58bd3 100644 --- a/boost/intrusive/detail/mpl.hpp +++ b/boost/intrusive/detail/mpl.hpp @@ -14,7 +14,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP #define BOOST_INTRUSIVE_DETAIL_MPL_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -315,7 +319,14 @@ template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_i ::boost::intrusive::detail::if_c \ <value, T, DefaultWrap>::type::TNAME type; \ }; \ - \ + // + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ template <typename T, typename DefaultType> \ struct boost_intrusive_eval_default_type_ ## TNAME \ { \ @@ -339,11 +350,6 @@ template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_i }; \ // -#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ - typename INSTANTIATION_NS_PREFIX \ - boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ -// - #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ typename INSTANTIATION_NS_PREFIX \ boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ @@ -367,6 +373,58 @@ struct TRAITS_PREFIX##_bool_is_true\ };\ // +#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ + template <typename U, typename Signature> \ + class TRAITS_NAME \ + { \ + private: \ + template<Signature> struct helper;\ + template<typename T> \ + static ::boost::intrusive::detail::yes_type check(helper<&T::FUNC_NAME>*); \ + template<typename T> static ::boost::intrusive::detail::no_type check(...); \ + public: \ + static const bool value = sizeof(check<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \ + }; \ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ +template <typename Type> \ +struct TRAITS_NAME \ +{ \ + struct BaseMixin \ + { \ + void FUNC_NAME(); \ + }; \ + struct Base : public Type, public BaseMixin { Base(); }; \ + template <typename T, T t> class Helper{}; \ + template <typename U> \ + static ::boost::intrusive::detail::no_type check(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \ + static ::boost::intrusive::detail::yes_type check(...); \ + static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(check((Base*)(0))); \ +};\ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ +BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ +\ +template <typename Type, class> \ +struct TRAITS_NAME \ + : public TRAITS_NAME##_ignore_signature<Type> \ +{};\ +// + + +template <typename T> +inline T* addressof(T& obj) +{ + return static_cast<T*> + (static_cast<void*> + (const_cast<char*> + (&reinterpret_cast<const char&>(obj)) + ) + ); +} + } //namespace detail } //namespace intrusive } //namespace boost diff --git a/boost/intrusive/detail/node_cloner_disposer.hpp b/boost/intrusive/detail/node_cloner_disposer.hpp index 2a18100205..65af3e37b8 100644 --- a/boost/intrusive/detail/node_cloner_disposer.hpp +++ b/boost/intrusive/detail/node_cloner_disposer.hpp @@ -13,11 +13,16 @@ #ifndef BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP #define BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include <boost/intrusive/link_mode.hpp> +#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/ebo_functor_holder.hpp> #include <boost/intrusive/detail/algo_type.hpp> #include <boost/intrusive/detail/assert.hpp> @@ -26,9 +31,10 @@ namespace boost { namespace intrusive { namespace detail { -template<class F, class ValueTraits, algo_types AlgoType> +template<class F, class ValueTraits, algo_types AlgoType, bool IsConst = true> struct node_cloner - : private ebo_functor_holder<F> + //Use public inheritance to avoid MSVC bugs with closures + : public ebo_functor_holder<F> { typedef ValueTraits value_traits; typedef typename value_traits::node_traits node_traits; @@ -45,6 +51,8 @@ struct node_cloner typedef typename value_traits::reference reference; typedef typename value_traits::const_reference const_reference; + typedef typename if_c<IsConst, const_reference, reference>::type reference_type; + node_cloner(F f, const ValueTraits *traits) : base_t(f), traits_(traits) {} @@ -52,7 +60,7 @@ struct node_cloner // tree-based containers use this method, which is proxy-reference friendly node_ptr operator()(const node_ptr & p) { - const_reference v = *traits_->to_value_ptr(p); + reference_type v = *traits_->to_value_ptr(p); node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); //Cloned node must be in default mode if the linking mode requires it if(safemode_or_autounlink) @@ -63,7 +71,7 @@ struct node_cloner // hashtables use this method, which is proxy-reference unfriendly node_ptr operator()(const node &to_clone) { - const value_type &v = + reference_type v = *traits_->to_value_ptr (pointer_traits<const_node_ptr>::pointer_to(to_clone)); node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); @@ -78,7 +86,8 @@ struct node_cloner template<class F, class ValueTraits, algo_types AlgoType> struct node_disposer - : private ebo_functor_holder<F> + //Use public inheritance to avoid MSVC bugs with closures + : public ebo_functor_holder<F> { typedef ValueTraits value_traits; typedef typename value_traits::node_traits node_traits; diff --git a/boost/intrusive/detail/node_holder.hpp b/boost/intrusive/detail/node_holder.hpp index 12732a87a7..b8dabef2df 100644 --- a/boost/intrusive/detail/node_holder.hpp +++ b/boost/intrusive/detail/node_holder.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP #define BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/node_to_value.hpp b/boost/intrusive/detail/node_to_value.hpp index 6ec3971239..5af3347345 100644 --- a/boost/intrusive/detail/node_to_value.hpp +++ b/boost/intrusive/detail/node_to_value.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP #define BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/parent_from_member.hpp b/boost/intrusive/detail/parent_from_member.hpp index 3dfe8d6461..30eba13e16 100644 --- a/boost/intrusive/detail/parent_from_member.hpp +++ b/boost/intrusive/detail/parent_from_member.hpp @@ -12,7 +12,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP #define BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -48,7 +52,7 @@ inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_t caster.ptr_to_member = ptr_to_member; return std::ptrdiff_t(caster.offset); - //Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member + //Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member //types dereference seems to be: // // vboffset = [compile_time_offset if 2-int ptr2memb] / diff --git a/boost/intrusive/detail/pointer_element.hpp b/boost/intrusive/detail/pointer_element.hpp index 1c17f419ec..dd26e3cf0b 100644 --- a/boost/intrusive/detail/pointer_element.hpp +++ b/boost/intrusive/detail/pointer_element.hpp @@ -11,11 +11,17 @@ #ifndef BOOST_INTRUSIVE_DETAIL_POINTER_ELEMENT_HPP #define BOOST_INTRUSIVE_DETAIL_POINTER_ELEMENT_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP #include <boost/intrusive/detail/workaround.hpp> +#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP namespace boost { namespace intrusive { @@ -118,14 +124,6 @@ template <typename T> struct first_param < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6, P7, P8> > { typedef T type; }; - template < template //10arg - <class,class,class,class,class,class,class,class,class,class,class - > class TemplateClass, class T - , class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> - struct first_param - < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9> > - { typedef T type; }; - #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template <typename T> diff --git a/boost/intrusive/detail/preprocessor.hpp b/boost/intrusive/detail/preprocessor.hpp deleted file mode 100644 index cdbc8a1d39..0000000000 --- a/boost/intrusive/detail/preprocessor.hpp +++ /dev/null @@ -1,42 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2008-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_PREPROCESSOR_HPP -#define BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP - -#if defined(_MSC_VER) -# pragma once -#endif - -#include <boost/intrusive/detail/config_begin.hpp> -#include <boost/intrusive/detail/workaround.hpp> - -#include <boost/preprocessor/cat.hpp> -#include <boost/preprocessor/repetition/enum.hpp> -#include <boost/preprocessor/repetition/enum_trailing_params.hpp> -#include <boost/preprocessor/repetition/enum_trailing.hpp> -#include <boost/preprocessor/arithmetic/sub.hpp> - - -#define BOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS 10 - -#define BOOST_INTRUSIVE_PP_IDENTITY(z, n, data) data - -#define BOOST_INTRUSIVE_PP_DECLVAL(z, n, data) \ -boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \ -//! - -#define BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \ - BOOST_PP_CAT(class P, n) = void \ -//! - -#include <boost/intrusive/detail/config_end.hpp> - -#endif //#ifndef BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP diff --git a/boost/intrusive/detail/rbtree_node.hpp b/boost/intrusive/detail/rbtree_node.hpp index ab50509c25..c4364399d8 100644 --- a/boost/intrusive/detail/rbtree_node.hpp +++ b/boost/intrusive/detail/rbtree_node.hpp @@ -14,7 +14,11 @@ #ifndef BOOST_INTRUSIVE_RBTREE_NODE_HPP #define BOOST_INTRUSIVE_RBTREE_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/reverse_iterator.hpp b/boost/intrusive/detail/reverse_iterator.hpp index 9f443ab4b2..6a6fee5ac2 100644 --- a/boost/intrusive/detail/reverse_iterator.hpp +++ b/boost/intrusive/detail/reverse_iterator.hpp @@ -10,19 +10,22 @@ // ///////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP -#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP +#ifndef BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include <boost/intrusive/detail/config_begin.hpp> -#include <boost/intrusive/detail/iiterator.hpp> +#include <boost/intrusive/detail/iterator.hpp> namespace boost { namespace intrusive { -namespace detail { template<class It> class reverse_iterator @@ -60,7 +63,7 @@ class reverse_iterator { It temp(m_current); --temp; return temp.operator->(); } reference operator[](difference_type off) const - { return this->m_current[-off]; } + { return this->m_current[-off-1]; } reverse_iterator& operator++() { --m_current; return *this; } @@ -130,10 +133,9 @@ class reverse_iterator It m_current; // the wrapped iterator }; -} //namespace detail -} //namespace intrusive -} //namespace boost +} //namespace intrusive { +} //namespace boost { #include <boost/intrusive/detail/config_end.hpp> -#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP +#endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/boost/intrusive/detail/simple_disposers.hpp b/boost/intrusive/detail/simple_disposers.hpp index af597722fa..1420b281b0 100644 --- a/boost/intrusive/detail/simple_disposers.hpp +++ b/boost/intrusive/detail/simple_disposers.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP #define BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/size_holder.hpp b/boost/intrusive/detail/size_holder.hpp index a733187733..de1933ed50 100644 --- a/boost/intrusive/detail/size_holder.hpp +++ b/boost/intrusive/detail/size_holder.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP #define BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/slist_iterator.hpp b/boost/intrusive/detail/slist_iterator.hpp index 579c660f57..80a6fef924 100644 --- a/boost/intrusive/detail/slist_iterator.hpp +++ b/boost/intrusive/detail/slist_iterator.hpp @@ -14,7 +14,11 @@ #ifndef BOOST_INTRUSIVE_SLIST_ITERATOR_HPP #define BOOST_INTRUSIVE_SLIST_ITERATOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/slist_node.hpp b/boost/intrusive/detail/slist_node.hpp index 437190e6c0..3d5fbfb6e5 100644 --- a/boost/intrusive/detail/slist_node.hpp +++ b/boost/intrusive/detail/slist_node.hpp @@ -14,7 +14,11 @@ #ifndef BOOST_INTRUSIVE_SLIST_NODE_HPP #define BOOST_INTRUSIVE_SLIST_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/std_fwd.hpp b/boost/intrusive/detail/std_fwd.hpp index b657c4acfe..0492c1dc3d 100644 --- a/boost/intrusive/detail/std_fwd.hpp +++ b/boost/intrusive/detail/std_fwd.hpp @@ -11,7 +11,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP #define BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -25,6 +29,12 @@ #pragma GCC diagnostic ignored "-Wc++11-extensions" #define BOOST_INTRUSIVE_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD #define BOOST_INTRUSIVE_STD_NS_END _LIBCPP_END_NAMESPACE_STD +#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6 + #define BOOST_INTRUSIVE_STD_NS_BEG namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION + #define BOOST_INTRUSIVE_STD_NS_END _GLIBCXX_END_NAMESPACE_VERSION } // namespace +#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE) //GCC >= 4.2 + #define BOOST_INTRUSIVE_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std) + #define BOOST_INTRUSIVE_STD_NS_END _GLIBCXX_END_NAMESPACE #else #define BOOST_INTRUSIVE_STD_NS_BEG namespace std{ #define BOOST_INTRUSIVE_STD_NS_END } @@ -51,4 +61,3 @@ BOOST_INTRUSIVE_STD_NS_END #endif //BOOST_INTRUSIVE_CLANG_INLINE_STD_NS #endif //#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP - diff --git a/boost/intrusive/detail/to_raw_pointer.hpp b/boost/intrusive/detail/to_raw_pointer.hpp index e7ebff9e5d..387f63f2a4 100644 --- a/boost/intrusive/detail/to_raw_pointer.hpp +++ b/boost/intrusive/detail/to_raw_pointer.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_TO_RAW_POINTER_HPP #define BOOST_INTRUSIVE_DETAIL_TO_RAW_POINTER_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/transform_iterator.hpp b/boost/intrusive/detail/transform_iterator.hpp index 698318be9b..89ec973967 100644 --- a/boost/intrusive/detail/transform_iterator.hpp +++ b/boost/intrusive/detail/transform_iterator.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP #define BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -90,16 +94,6 @@ class transform_iterator friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) { return !(i == i2); } -/* - friend bool operator> (const transform_iterator& i, const transform_iterator& i2) - { return i2 < i; } - - friend bool operator<= (const transform_iterator& i, const transform_iterator& i2) - { return !(i > i2); } - - friend bool operator>= (const transform_iterator& i, const transform_iterator& i2) - { return !(i < i2); } -*/ friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) { return i2.distance_to(i); } diff --git a/boost/intrusive/detail/tree_iterator.hpp b/boost/intrusive/detail/tree_iterator.hpp index c3b599d190..525761f3d6 100644 --- a/boost/intrusive/detail/tree_iterator.hpp +++ b/boost/intrusive/detail/tree_iterator.hpp @@ -13,14 +13,18 @@ #ifndef BOOST_INTRUSIVE_TREE_ITERATOR_HPP #define BOOST_INTRUSIVE_TREE_ITERATOR_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/std_fwd.hpp> #include <boost/intrusive/detail/iiterator.hpp> -#include <boost/intrusive/bstree_algorithms.hpp> +#include <boost/intrusive/detail/bstree_algorithms_base.hpp> namespace boost { namespace intrusive { @@ -46,8 +50,12 @@ class tree_iterator typedef typename types_t::node node; typedef typename types_t::node_ptr node_ptr; typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; + typedef bstree_algorithms_base<node_traits> node_algorithms; + static const bool stateful_value_traits = types_t::stateful_value_traits; - typedef bstree_algorithms<node_traits> node_algorithms; + + void unspecified_bool_type_func() const {} + typedef void (tree_iterator::*unspecified_bool_type)() const; public: typedef typename types_t::iterator_traits::difference_type difference_type; @@ -100,6 +108,21 @@ class tree_iterator return result; } + void go_left() + { members_.nodeptr_ = node_traits::get_left(members_.nodeptr_); } + + void go_right() + { members_.nodeptr_ = node_traits::get_right(members_.nodeptr_); } + + void go_parent() + { members_.nodeptr_ = node_traits::get_parent(members_.nodeptr_); } + + operator unspecified_bool_type() const + { return members_.nodeptr_ ? &tree_iterator::unspecified_bool_type_func : 0; } + + bool operator! () const + { return !members_.nodeptr_; } + friend bool operator== (const tree_iterator& l, const tree_iterator& r) { return l.pointed_node() == r.pointed_node(); } diff --git a/boost/intrusive/detail/tree_node.hpp b/boost/intrusive/detail/tree_node.hpp index 653d6fcf07..e36a82a6d6 100644 --- a/boost/intrusive/detail/tree_node.hpp +++ b/boost/intrusive/detail/tree_node.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_TREE_NODE_HPP #define BOOST_INTRUSIVE_TREE_NODE_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/uncast.hpp b/boost/intrusive/detail/uncast.hpp index 944b6cd617..7db97b7457 100644 --- a/boost/intrusive/detail/uncast.hpp +++ b/boost/intrusive/detail/uncast.hpp @@ -13,7 +13,11 @@ #ifndef BOOST_INTRUSIVE_DETAIL_UNCAST_HPP #define BOOST_INTRUSIVE_DETAIL_UNCAST_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif diff --git a/boost/intrusive/detail/workaround.hpp b/boost/intrusive/detail/workaround.hpp index ad00691f25..b73f4ef8bf 100644 --- a/boost/intrusive/detail/workaround.hpp +++ b/boost/intrusive/detail/workaround.hpp @@ -8,10 +8,14 @@ // ////////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_INTRUSIVE_DETAIL_WRKRND_HPP -#define BOOST_INTRUSIVE_DETAIL_WRKRND_HPP +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#define BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP -#if defined(_MSC_VER) +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif @@ -26,5 +30,9 @@ //Macros for documentation purposes. For code, expands to the argument #define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE #define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE +#define BOOST_INTRUSIVE_DOC1ST(TYPE1, TYPE2) TYPE2 +#define BOOST_INTRUSIVE_I , +#define BOOST_INTRUSIVE_DOCIGN(T1) T1 + -#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WRKRND_HPP +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP |