summaryrefslogtreecommitdiff
path: root/boost/log/utility/type_dispatch/type_dispatcher.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/log/utility/type_dispatch/type_dispatcher.hpp')
-rw-r--r--boost/log/utility/type_dispatch/type_dispatcher.hpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/boost/log/utility/type_dispatch/type_dispatcher.hpp b/boost/log/utility/type_dispatch/type_dispatcher.hpp
new file mode 100644
index 0000000000..36e1ce8b05
--- /dev/null
+++ b/boost/log/utility/type_dispatch/type_dispatcher.hpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file type_dispatcher.hpp
+ * \author Andrey Semashev
+ * \date 15.04.2007
+ *
+ * The header contains definition of generic type dispatcher interfaces.
+ */
+
+#ifndef BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
+#define BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
+
+#include <typeinfo>
+#include <boost/static_assert.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/visible_type.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * \brief A type dispatcher interface
+ *
+ * All type dispatchers support this interface. It is used to acquire the
+ * visitor interface for the requested type.
+ */
+class type_dispatcher
+{
+public:
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+ //! The base class for type dispatcher callbacks
+ class callback_base
+ {
+ protected:
+ void* m_pVisitor;
+ void* m_pTrampoline;
+
+ public:
+ explicit callback_base(void* visitor = 0, void* tramp = 0) BOOST_NOEXCEPT :
+ m_pVisitor(visitor),
+ m_pTrampoline(tramp)
+ {
+ }
+ template< typename ValueT >
+ explicit callback_base(void* visitor, void (*tramp)(void*, ValueT const&)) BOOST_NOEXCEPT :
+ m_pVisitor(visitor)
+ {
+ typedef void (*trampoline_t)(void*, ValueT const&);
+ 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");
+ union
+ {
+ void* as_pvoid;
+ trampoline_t as_trampoline;
+ }
+ caster;
+ caster.as_trampoline = tramp;
+ m_pTrampoline = caster.as_pvoid;
+ }
+
+ template< typename VisitorT, typename T >
+ static void trampoline(void* visitor, T const& value)
+ {
+ (*static_cast< VisitorT* >(visitor))(value);
+ }
+ };
+
+ //! An interface to the callback for the concrete type visitor
+ template< typename T >
+ class callback :
+ private callback_base
+ {
+ private:
+ //! Type of the trampoline method
+ typedef void (*trampoline_t)(void*, T const&);
+
+ public:
+ //! The type, which the visitor is able to consume
+ typedef T supported_type;
+
+ public:
+ callback() BOOST_NOEXCEPT : callback_base()
+ {
+ }
+ explicit callback(callback_base const& base) BOOST_NOEXCEPT : callback_base(base)
+ {
+ }
+
+ void operator() (T const& value) const
+ {
+ 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");
+ union
+ {
+ void* as_pvoid;
+ trampoline_t as_trampoline;
+ }
+ caster;
+ caster.as_pvoid = this->m_pTrampoline;
+ (caster.as_trampoline)(this->m_pVisitor, value);
+ }
+
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+
+ bool operator! () const BOOST_NOEXCEPT { return (this->m_pVisitor == 0); }
+ };
+
+#else // BOOST_LOG_DOXYGEN_PASS
+
+ /*!
+ * This interface is used by type dispatchers to consume the dispatched value.
+ */
+ template< typename T >
+ class callback
+ {
+ public:
+ /*!
+ * The operator invokes the visitor-specific logic with the given value
+ *
+ * \param value The dispatched value
+ */
+ void operator() (T const& value) const;
+
+ /*!
+ * The operator checks if the visitor is attached to a receiver
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+
+ /*!
+ * The operator checks if the visitor is not attached to a receiver
+ */
+ bool operator! () const BOOST_NOEXCEPT;
+ };
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+protected:
+ //! Pointer to the callback acquisition method
+ typedef callback_base (*get_callback_impl_type)(type_dispatcher*, std::type_info const&);
+
+private:
+ //! Pointer to the callback acquisition method
+ get_callback_impl_type m_get_callback_impl;
+
+protected:
+ /*!
+ * Initializing constructor
+ */
+ explicit type_dispatcher(get_callback_impl_type get_callback_impl) BOOST_NOEXCEPT : m_get_callback_impl(get_callback_impl)
+ {
+ }
+
+ // Destructor and copying can only be called from the derived classes
+ BOOST_DEFAULTED_FUNCTION(~type_dispatcher(), {})
+ BOOST_DEFAULTED_FUNCTION(type_dispatcher(type_dispatcher const& that), : m_get_callback_impl(that.m_get_callback_impl) {})
+ BOOST_DEFAULTED_FUNCTION(type_dispatcher& operator= (type_dispatcher const& that), { m_get_callback_impl = that.m_get_callback_impl; return *this; })
+
+public:
+ /*!
+ * The method requests a callback for the value of type \c T
+ *
+ * \return The type-specific callback or an empty value, if the type is not supported
+ */
+ template< typename T >
+ callback< T > get_callback()
+ {
+ return callback< T >((this->m_get_callback_impl)(this, typeid(boost::log::aux::visible_type< T >)));
+ }
+};
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_