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