]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/include/boost/log/utility/type_dispatch/type_dispatcher.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / log / include / boost / log / utility / type_dispatch / type_dispatcher.hpp
1 /*
2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7 /*!
8 * \file type_dispatcher.hpp
9 * \author Andrey Semashev
10 * \date 15.04.2007
11 *
12 * The header contains definition of generic type dispatcher interfaces.
13 */
14
15 #ifndef BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
16 #define BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
17
18 #include <boost/type_index.hpp>
19 #include <boost/static_assert.hpp>
20 #include <boost/log/detail/config.hpp>
21 #include <boost/utility/explicit_operator_bool.hpp>
22 #include <boost/log/detail/header.hpp>
23
24 #ifdef BOOST_HAS_PRAGMA_ONCE
25 #pragma once
26 #endif
27
28 namespace boost {
29
30 BOOST_LOG_OPEN_NAMESPACE
31
32 /*!
33 * \brief A type dispatcher interface
34 *
35 * All type dispatchers support this interface. It is used to acquire the
36 * visitor interface for the requested type.
37 */
38 class type_dispatcher
39 {
40 public:
41
42 #ifndef BOOST_LOG_DOXYGEN_PASS
43
44 //! The base class for type dispatcher callbacks
45 class callback_base
46 {
47 protected:
48 void* m_pVisitor;
49 void* m_pTrampoline;
50
51 public:
52 explicit callback_base(void* visitor = 0, void* tramp = 0) BOOST_NOEXCEPT :
53 m_pVisitor(visitor),
54 m_pTrampoline(tramp)
55 {
56 }
57 template< typename ValueT >
58 explicit callback_base(void* visitor, void (*tramp)(void*, ValueT const&)) BOOST_NOEXCEPT :
59 m_pVisitor(visitor)
60 {
61 typedef void (*trampoline_t)(void*, ValueT const&);
62 BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
63 union
64 {
65 void* as_pvoid;
66 trampoline_t as_trampoline;
67 }
68 caster;
69 caster.as_trampoline = tramp;
70 m_pTrampoline = caster.as_pvoid;
71 }
72
73 template< typename VisitorT, typename T >
74 static void trampoline(void* visitor, T const& value)
75 {
76 (*static_cast< VisitorT* >(visitor))(value);
77 }
78 };
79
80 //! An interface to the callback for the concrete type visitor
81 template< typename T >
82 class callback :
83 private callback_base
84 {
85 private:
86 //! Type of the trampoline method
87 typedef void (*trampoline_t)(void*, T const&);
88
89 public:
90 //! The type, which the visitor is able to consume
91 typedef T supported_type;
92
93 public:
94 callback() BOOST_NOEXCEPT : callback_base()
95 {
96 }
97 explicit callback(callback_base const& base) BOOST_NOEXCEPT : callback_base(base)
98 {
99 }
100
101 void operator() (T const& value) const
102 {
103 BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
104 union
105 {
106 void* as_pvoid;
107 trampoline_t as_trampoline;
108 }
109 caster;
110 caster.as_pvoid = this->m_pTrampoline;
111 (caster.as_trampoline)(this->m_pVisitor, value);
112 }
113
114 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
115
116 bool operator! () const BOOST_NOEXCEPT { return (this->m_pVisitor == 0); }
117 };
118
119 #else // BOOST_LOG_DOXYGEN_PASS
120
121 /*!
122 * This interface is used by type dispatchers to consume the dispatched value.
123 */
124 template< typename T >
125 class callback
126 {
127 public:
128 /*!
129 * The operator invokes the visitor-specific logic with the given value
130 *
131 * \param value The dispatched value
132 */
133 void operator() (T const& value) const;
134
135 /*!
136 * The operator checks if the visitor is attached to a receiver
137 */
138 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
139
140 /*!
141 * The operator checks if the visitor is not attached to a receiver
142 */
143 bool operator! () const BOOST_NOEXCEPT;
144 };
145
146 #endif // BOOST_LOG_DOXYGEN_PASS
147
148 protected:
149 //! Pointer to the callback acquisition method
150 typedef callback_base (*get_callback_impl_type)(type_dispatcher*, typeindex::type_index);
151
152 private:
153 //! Pointer to the callback acquisition method
154 get_callback_impl_type m_get_callback_impl;
155
156 protected:
157 /*!
158 * Initializing constructor
159 */
160 explicit type_dispatcher(get_callback_impl_type get_callback_impl) BOOST_NOEXCEPT : m_get_callback_impl(get_callback_impl)
161 {
162 }
163
164 // Destructor and copying can only be called from the derived classes
165 BOOST_DEFAULTED_FUNCTION(~type_dispatcher(), {})
166 BOOST_DEFAULTED_FUNCTION(type_dispatcher(type_dispatcher const& that), : m_get_callback_impl(that.m_get_callback_impl) {})
167 BOOST_DEFAULTED_FUNCTION(type_dispatcher& operator= (type_dispatcher const& that), { m_get_callback_impl = that.m_get_callback_impl; return *this; })
168
169 public:
170 /*!
171 * The method requests a callback for the value of type \c T
172 *
173 * \return The type-specific callback or an empty value, if the type is not supported
174 */
175 template< typename T >
176 callback< T > get_callback()
177 {
178 return callback< T >((this->m_get_callback_impl)(this, typeindex::type_id< T >()));
179 }
180 };
181
182 BOOST_LOG_CLOSE_NAMESPACE // namespace log
183
184 } // namespace boost
185
186 #include <boost/log/detail/footer.hpp>
187
188 #endif // BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_