1 ///////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2014-2014 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // See http://www.boost.org/libs/intrusive for documentation. 10 // 11 ///////////////////////////////////////////////////////////////////////////// 12 13 #ifndef BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP 14 #define BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP 15 16 #ifndef BOOST_CONFIG_HPP 17 # include <boost/config.hpp> 18 #endif 19 20 #if defined(BOOST_HAS_PRAGMA_ONCE) 21 # pragma once 22 #endif 23 24 #include <boost/intrusive/link_mode.hpp> 25 #include <boost/intrusive/detail/mpl.hpp> 26 #include <boost/intrusive/detail/ebo_functor_holder.hpp> 27 #include <boost/intrusive/detail/algo_type.hpp> 28 #include <boost/intrusive/detail/assert.hpp> 29 30 namespace boost { 31 namespace intrusive { 32 namespace detail { 33 34 template<class F, class ValueTraits, algo_types AlgoType, bool IsConst = true> 35 struct node_cloner 36 //Use public inheritance to avoid MSVC bugs with closures 37 : public ebo_functor_holder<F> 38 { 39 typedef ValueTraits value_traits; 40 typedef typename value_traits::node_traits node_traits; 41 typedef typename node_traits::node_ptr node_ptr; 42 typedef ebo_functor_holder<F> base_t; 43 typedef typename get_algo< AlgoType 44 , node_traits>::type node_algorithms; 45 static const bool safemode_or_autounlink = 46 is_safe_autounlink<value_traits::link_mode>::value; 47 typedef typename value_traits::value_type value_type; 48 typedef typename value_traits::pointer pointer; 49 typedef typename value_traits::const_pointer const_pointer; 50 typedef typename node_traits::node node; 51 typedef typename value_traits::const_node_ptr const_node_ptr; 52 typedef typename pointer_traits<pointer>::reference reference; 53 typedef typename pointer_traits 54 <const_pointer>::reference const_reference; 55 typedef typename if_c<IsConst, const_reference, reference>::type reference_type; 56 node_clonerboost::intrusive::detail::node_cloner57 node_cloner(F f, const ValueTraits *traits) 58 : base_t(f), traits_(traits) 59 {} 60 61 // tree-based containers use this method, which is proxy-reference friendly operator ()boost::intrusive::detail::node_cloner62 BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(const node_ptr & p) 63 { 64 reference_type v = *traits_->to_value_ptr(p); 65 node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); 66 //Cloned node must be in default mode if the linking mode requires it 67 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n)); 68 return n; 69 } 70 71 const ValueTraits * const traits_; 72 }; 73 74 template<class F, class ValueTraits, algo_types AlgoType> 75 struct node_disposer 76 //Use public inheritance to avoid MSVC bugs with closures 77 : public ebo_functor_holder<F> 78 { 79 typedef ValueTraits value_traits; 80 typedef typename value_traits::node_traits node_traits; 81 typedef typename node_traits::node_ptr node_ptr; 82 typedef ebo_functor_holder<F> base_t; 83 typedef typename get_algo< AlgoType 84 , node_traits>::type node_algorithms; 85 static const bool safemode_or_autounlink = 86 is_safe_autounlink<value_traits::link_mode>::value; 87 node_disposerboost::intrusive::detail::node_disposer88 node_disposer(F f, const ValueTraits *cont) 89 : base_t(f), traits_(cont) 90 {} 91 operator ()boost::intrusive::detail::node_disposer92 BOOST_INTRUSIVE_FORCEINLINE void operator()(const node_ptr & p) 93 { 94 if(safemode_or_autounlink) 95 node_algorithms::init(p); 96 base_t::get()(traits_->to_value_ptr(p)); 97 } 98 const ValueTraits * const traits_; 99 }; 100 101 } //namespace detail{ 102 } //namespace intrusive{ 103 } //namespace boost{ 104 105 #endif //BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP 106