Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file keyword.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 29.01.2012 Chris@16: * Chris@16: * The header contains attribute keyword declaration. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_EXPRESSIONS_KEYWORD_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_EXPRESSIONS_KEYWORD_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace expressions { Chris@16: Chris@16: /*! Chris@16: * This class implements an expression template keyword. It is used to start template expressions involving attribute values. Chris@16: */ Chris@16: template< typename DescriptorT, template< typename > class ActorT > Chris@16: struct attribute_keyword Chris@16: { Chris@16: //! Self type Chris@16: typedef attribute_keyword this_type; Chris@16: //! Attribute descriptor type Chris@16: typedef DescriptorT descriptor_type; Chris@16: Chris@16: BOOST_PROTO_BASIC_EXTENDS(typename proto::terminal< descriptor_type >::type, this_type, phoenix::phoenix_domain) Chris@16: Chris@16: //! Attribute value type Chris@16: typedef typename descriptor_type::value_type value_type; Chris@16: Chris@16: //! Returns attribute name Chris@16: static attribute_name get_name() { return descriptor_type::get_name(); } Chris@16: Chris@16: //! Expression with cached attribute name Chris@16: typedef attribute_actor< Chris@16: value_type, Chris@16: fallback_to_none, Chris@16: descriptor_type, Chris@16: ActorT Chris@16: > or_none_result_type; Chris@16: Chris@16: //! Generates an expression that extracts the attribute value or a default value Chris@16: static or_none_result_type or_none() Chris@16: { Chris@16: typedef typename or_none_result_type::terminal_type result_terminal; Chris@16: typename or_none_result_type::base_type act = {{ result_terminal(get_name()) }}; Chris@16: return or_none_result_type(act); Chris@16: } Chris@16: Chris@16: //! Expression with cached attribute name Chris@16: typedef attribute_actor< Chris@16: value_type, Chris@16: fallback_to_throw, Chris@16: descriptor_type, Chris@16: ActorT Chris@16: > or_throw_result_type; Chris@16: Chris@16: //! Generates an expression that extracts the attribute value or throws an exception Chris@16: static or_throw_result_type or_throw() Chris@16: { Chris@16: typedef typename or_throw_result_type::terminal_type result_terminal; Chris@16: typename or_throw_result_type::base_type act = {{ result_terminal(get_name()) }}; Chris@16: return or_throw_result_type(act); Chris@16: } Chris@16: Chris@16: //! Generates an expression that extracts the attribute value or a default value Chris@16: template< typename DefaultT > Chris@16: static attribute_actor< Chris@16: value_type, Chris@16: fallback_to_default< DefaultT >, Chris@16: descriptor_type, Chris@16: ActorT Chris@16: > or_default(DefaultT const& def_val) Chris@16: { Chris@16: typedef attribute_actor< Chris@16: value_type, Chris@16: fallback_to_default< DefaultT >, Chris@16: descriptor_type, Chris@16: ActorT Chris@16: > or_default_result_type; Chris@16: typedef typename or_default_result_type::terminal_type result_terminal; Chris@16: typename or_default_result_type::base_type act = {{ result_terminal(get_name(), def_val) }}; Chris@16: return or_default_result_type(act); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace expressions Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: namespace proto { Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: // This hack is needed in order to cache attribute name into the expression terminal when the template Chris@16: // expression is constructed. The standard way through a custom domain doesn't work because phoenix::actor Chris@16: // is bound to phoenix_domain. Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: typedef boost::log::expressions::attribute_keyword< DescriptorT, ActorT > keyword_type; Chris@16: typedef typename keyword_type::or_none_result_type result_type; Chris@16: Chris@16: result_type operator() (keyword_type const& keyword) const Chris@16: { Chris@16: return keyword.or_none(); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >&, DomainT > : Chris@16: public protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT > const&, DomainT > : Chris@16: public protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::reference_wrapper< boost::log::expressions::attribute_keyword< DescriptorT, ActorT > >, DomainT > : Chris@16: public protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::reference_wrapper< boost::log::expressions::attribute_keyword< DescriptorT, ActorT > > const, DomainT > : Chris@16: public protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::reference_wrapper< const boost::log::expressions::attribute_keyword< DescriptorT, ActorT > >, DomainT > : Chris@16: public protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename DescriptorT, template< typename > class ActorT, typename DomainT > Chris@16: struct protoify< boost::reference_wrapper< const boost::log::expressions::attribute_keyword< DescriptorT, ActorT > > const, DomainT > : Chris@16: public protoify< boost::log::expressions::attribute_keyword< DescriptorT, ActorT >, DomainT > Chris@16: { Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: } // namespace proto Chris@16: Chris@16: #endif // !defined(BOOST_LOG_DOXYGEN_PASS) Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE_IMPL(keyword_, name_, value_type_, tag_ns_)\ Chris@16: namespace tag_ns_\ Chris@16: {\ Chris@16: struct keyword_ :\ Chris@16: public ::boost::log::expressions::keyword_descriptor\ Chris@16: {\ Chris@16: typedef value_type_ value_type;\ Chris@16: static ::boost::log::attribute_name get_name() { return ::boost::log::attribute_name(name_); }\ Chris@16: };\ Chris@16: }\ Chris@16: typedef ::boost::log::expressions::attribute_keyword< tag_ns_::keyword_ > BOOST_PP_CAT(keyword_, _type); Chris@16: Chris@16: #define BOOST_LOG_ATTRIBUTE_KEYWORD_IMPL(keyword_, name_, value_type_, tag_ns_)\ Chris@16: BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE_IMPL(keyword_, name_, value_type_, tag_ns_)\ Chris@16: const BOOST_PP_CAT(keyword_, _type) keyword_ = {}; Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares an attribute keyword type Chris@16: * Chris@16: * The macro should be used at a namespace scope. It expands into an attribute keyword type definition, including the Chris@16: * \c tag namespace and the keyword tag type within which has the following layout: Chris@16: * Chris@16: * \code Chris@16: * namespace tag Chris@16: * { Chris@16: * struct keyword_ : Chris@16: * public boost::log::expressions::keyword_descriptor Chris@16: * { Chris@16: * typedef value_type_ value_type; Chris@16: * static boost::log::attribute_name get_name(); Chris@16: * }; Chris@16: * } Chris@16: * Chris@16: * typedef boost::log::expressions::attribute_keyword< tag::keyword_ > keyword_type; Chris@16: * \endcode Chris@16: * Chris@16: * The \c get_name method returns the attribute name. Chris@16: * Chris@16: * \note This macro only defines the type of the keyword. To also define the keyword object, use Chris@16: * the \c BOOST_LOG_ATTRIBUTE_KEYWORD macro instead. Chris@16: * Chris@16: * \param keyword_ Keyword name Chris@16: * \param name_ Attribute name string Chris@16: * \param value_type_ Attribute value type Chris@16: */ Chris@16: #define BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE(keyword_, name_, value_type_)\ Chris@16: BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE_IMPL(keyword_, name_, value_type_, tag) Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares an attribute keyword Chris@16: * Chris@16: * The macro provides definitions similar to \c BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE and additionally Chris@16: * defines the keyword object. Chris@16: * Chris@16: * \param keyword_ Keyword name Chris@16: * \param name_ Attribute name string Chris@16: * \param value_type_ Attribute value type Chris@16: */ Chris@16: #define BOOST_LOG_ATTRIBUTE_KEYWORD(keyword_, name_, value_type_)\ Chris@16: BOOST_LOG_ATTRIBUTE_KEYWORD_IMPL(keyword_, name_, value_type_, tag) Chris@16: Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_LOG_TRIVIAL_HPP_INCLUDED_) Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_LOG_EXPRESSIONS_KEYWORD_HPP_INCLUDED_