123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /*
- * Copyright Andrey Semashev 2007 - 2015.
- * 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 <boost/type_index.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/core/explicit_operator_bool.hpp>
- #include <boost/log/detail/config.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*, typeindex::type_index);
- 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, typeindex::type_id< T >()));
- }
- };
- BOOST_LOG_CLOSE_NAMESPACE // namespace log
- } // namespace boost
- #include <boost/log/detail/footer.hpp>
- #endif // BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
|