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
28namespace boost {
29namespace intrusive {
30namespace detail {
31
32template<class VoidPointer>
33struct dummy_constptr
34{
35 typedef typename boost::intrusive::pointer_traits<VoidPointer>::
36 template rebind_pointer<const void>::type ConstVoidPtr;
37
38 explicit dummy_constptr(ConstVoidPtr)
39 {}
40
41 dummy_constptr()
42 {}
43
44 ConstVoidPtr get_ptr() const
45 { return ConstVoidPtr(); }
46};
47
48template<class VoidPointer>
49struct constptr
50{
51 typedef typename boost::intrusive::pointer_traits<VoidPointer>::
52 template rebind_pointer<const void>::type ConstVoidPtr;
53
54 constptr()
55 {}
56
57 explicit constptr(const ConstVoidPtr &ptr)
58 : const_void_ptr_(ptr)
59 {}
60
61 const void *get_ptr() const
62 { return boost::movelib::to_raw_pointer(const_void_ptr_); }
63
64 ConstVoidPtr const_void_ptr_;
65};
66
67template <class VoidPointer, bool store_ptr>
68struct select_constptr
69{
70 typedef typename if_c
71 < store_ptr
72 , constptr<VoidPointer>
73 , dummy_constptr<VoidPointer>
74 >::type type;
75};
76
77
78template<class ValueTraits, bool IsConst>
79struct 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
106 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
113 const_value_traits_ptr get_value_traits() const
114 { return pointer_traits<const_value_traits_ptr>::static_cast_from(Base::get_ptr()); }
115
116 result_type to_value(first_argument_type arg, false_) const
117 { return *(value_traits::to_value_ptr(pointer_traits<npointer>::pointer_to(arg))); }
118
119 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
122 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