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_TO_VALUE_HPP
14 #define BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_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/pointer_traits.hpp>
25 #include <boost/intrusive/detail/mpl.hpp>
26 #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
27 
28 namespace boost {
29 namespace intrusive {
30 namespace detail {
31 
32 template<class VoidPointer>
33 struct dummy_constptr
34 {
35    typedef typename boost::intrusive::pointer_traits<VoidPointer>::
36       template rebind_pointer<const void>::type ConstVoidPtr;
37 
dummy_constptrboost::intrusive::detail::dummy_constptr38    explicit dummy_constptr(ConstVoidPtr)
39    {}
40 
dummy_constptrboost::intrusive::detail::dummy_constptr41    dummy_constptr()
42    {}
43 
get_ptrboost::intrusive::detail::dummy_constptr44    ConstVoidPtr get_ptr() const
45    {  return ConstVoidPtr();  }
46 };
47 
48 template<class VoidPointer>
49 struct constptr
50 {
51    typedef typename boost::intrusive::pointer_traits<VoidPointer>::
52       template rebind_pointer<const void>::type ConstVoidPtr;
53 
constptrboost::intrusive::detail::constptr54    constptr()
55    {}
56 
constptrboost::intrusive::detail::constptr57    explicit constptr(const ConstVoidPtr &ptr)
58       :  const_void_ptr_(ptr)
59    {}
60 
get_ptrboost::intrusive::detail::constptr61    const void *get_ptr() const
62    {  return boost::intrusive::detail::to_raw_pointer(const_void_ptr_);  }
63 
64    ConstVoidPtr const_void_ptr_;
65 };
66 
67 template <class VoidPointer, bool store_ptr>
68 struct select_constptr
69 {
70    typedef typename if_c
71       < store_ptr
72       , constptr<VoidPointer>
73       , dummy_constptr<VoidPointer>
74       >::type type;
75 };
76 
77 
78 template<class ValueTraits, bool IsConst>
79 struct node_to_value
80    :  public select_constptr
81       < typename pointer_traits
82             <typename ValueTraits::pointer>::template rebind_pointer<void>::type
83       , is_stateful_value_traits<ValueTraits>::value
84       >::type
85 {
86    static const bool stateful_value_traits = is_stateful_value_traits<ValueTraits>::value;
87    typedef typename select_constptr
88       < typename pointer_traits
89             <typename ValueTraits::pointer>::
90                template rebind_pointer<void>::type
91       , stateful_value_traits >::type                 Base;
92 
93    typedef ValueTraits                                 value_traits;
94    typedef typename value_traits::value_type           value_type;
95    typedef typename value_traits::node_traits::node    node;
96    typedef typename add_const_if_c
97          <value_type, IsConst>::type                   vtype;
98    typedef typename add_const_if_c
99          <node, IsConst>::type                         ntype;
100    typedef typename pointer_traits
101       <typename ValueTraits::pointer>::
102          template rebind_pointer<ntype>::type          npointer;
103    typedef typename pointer_traits<npointer>::
104       template rebind_pointer<const ValueTraits>::type const_value_traits_ptr;
105 
node_to_valueboost::intrusive::detail::node_to_value106    node_to_value(const const_value_traits_ptr &ptr)
107       :  Base(ptr)
108    {}
109 
110    typedef vtype &                                 result_type;
111    typedef ntype &                                 first_argument_type;
112 
get_value_traitsboost::intrusive::detail::node_to_value113    const_value_traits_ptr get_value_traits() const
114    {  return pointer_traits<const_value_traits_ptr>::static_cast_from(Base::get_ptr());  }
115 
to_valueboost::intrusive::detail::node_to_value116    result_type to_value(first_argument_type arg, false_) const
117    {  return *(value_traits::to_value_ptr(pointer_traits<npointer>::pointer_to(arg)));  }
118 
to_valueboost::intrusive::detail::node_to_value119    result_type to_value(first_argument_type arg, true_) const
120    {  return *(this->get_value_traits()->to_value_ptr(pointer_traits<npointer>::pointer_to(arg))); }
121 
operator ()boost::intrusive::detail::node_to_value122    result_type operator()(first_argument_type arg) const
123    {  return this->to_value(arg, bool_<stateful_value_traits>()); }
124 };
125 
126 }  //namespace detail{
127 }  //namespace intrusive{
128 }  //namespace boost{
129 
130 #endif //BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP
131