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