Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:19

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   value_visitation.hpp
0009  * \author Andrey Semashev
0010  * \date   01.03.2008
0011  *
0012  * The header contains implementation of convenience tools to apply visitors to an attribute value
0013  * in the view.
0014  */
0015 
0016 #ifndef BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
0017 #define BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
0018 
0019 #include <boost/core/explicit_operator_bool.hpp>
0020 #include <boost/log/detail/config.hpp>
0021 #include <boost/log/exceptions.hpp>
0022 #include <boost/log/core/record.hpp>
0023 #include <boost/log/attributes/attribute_name.hpp>
0024 #include <boost/log/attributes/attribute_value.hpp>
0025 #include <boost/log/attributes/attribute.hpp>
0026 #include <boost/log/attributes/attribute_value_set.hpp>
0027 #include <boost/log/attributes/value_visitation_fwd.hpp>
0028 #include <boost/log/attributes/fallback_policy.hpp>
0029 #include <boost/log/expressions/keyword_fwd.hpp>
0030 #include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
0031 #include <boost/log/detail/header.hpp>
0032 
0033 #ifdef BOOST_HAS_PRAGMA_ONCE
0034 #pragma once
0035 #endif
0036 
0037 namespace boost {
0038 
0039 BOOST_LOG_OPEN_NAMESPACE
0040 
0041 /*!
0042  * \brief The class represents attribute value visitation result
0043  *
0044  * The main purpose of this class is to provide a convenient interface for checking
0045  * whether the attribute value visitation succeeded or not. It also allows to discover
0046  * the actual cause of failure, should the operation fail.
0047  */
0048 class visitation_result
0049 {
0050 public:
0051     //! Error codes for attribute value visitation
0052     enum error_code
0053     {
0054         ok,                     //!< The attribute value has been visited successfully
0055         value_not_found,        //!< The attribute value is not present in the view
0056         value_has_invalid_type  //!< The attribute value is present in the view, but has an unexpected type
0057     };
0058 
0059 private:
0060     error_code m_code;
0061 
0062 public:
0063     /*!
0064      * Initializing constructor. Creates the result that is equivalent to the
0065      * specified error code.
0066      */
0067     BOOST_CONSTEXPR visitation_result(error_code code = ok) BOOST_NOEXCEPT : m_code(code) {}
0068 
0069     /*!
0070      * Checks if the visitation was successful.
0071      *
0072      * \return \c true if the value was visited successfully, \c false otherwise.
0073      */
0074     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0075     /*!
0076      * Checks if the visitation was unsuccessful.
0077      *
0078      * \return \c false if the value was visited successfully, \c true otherwise.
0079      */
0080     bool operator! () const BOOST_NOEXCEPT { return (m_code != ok); }
0081 
0082     /*!
0083      * \return The actual result code of value visitation
0084      */
0085     error_code code() const BOOST_NOEXCEPT { return m_code; }
0086 };
0087 
0088 /*!
0089  * \brief Generic attribute value visitor invoker
0090  *
0091  * Attribute value invoker is a functional object that attempts to find and extract the stored
0092  * attribute value from the attribute value view or a log record. The extracted value is passed to
0093  * a unary function object (the visitor) provided by user.
0094  *
0095  * The invoker can be specialized on one or several attribute value types that should be
0096  * specified in the second template argument.
0097  */
0098 template< typename T, typename FallbackPolicyT >
0099 class value_visitor_invoker :
0100     private FallbackPolicyT
0101 {
0102     typedef value_visitor_invoker< T, FallbackPolicyT > this_type;
0103 
0104 public:
0105     //! Attribute value types
0106     typedef T value_type;
0107 
0108     //! Fallback policy
0109     typedef FallbackPolicyT fallback_policy;
0110 
0111     //! Function object result type
0112     typedef visitation_result result_type;
0113 
0114 public:
0115     /*!
0116      * Default constructor
0117      */
0118     BOOST_DEFAULTED_FUNCTION(value_visitor_invoker(), {})
0119 
0120     /*!
0121      * Copy constructor
0122      */
0123     value_visitor_invoker(value_visitor_invoker const& that) : fallback_policy(static_cast< fallback_policy const& >(that))
0124     {
0125     }
0126 
0127     /*!
0128      * Initializing constructor
0129      *
0130      * \param arg Fallback policy argument
0131      */
0132     template< typename U >
0133     explicit value_visitor_invoker(U const& arg) : fallback_policy(arg) {}
0134 
0135     /*!
0136      * Visitation operator. Attempts to acquire the stored value of one of the supported types. If acquisition succeeds,
0137      * the value is passed to \a visitor.
0138      *
0139      * \param attr An attribute value to apply the visitor to.
0140      * \param visitor A receiving function object to pass the attribute value to.
0141      * \return The result of visitation.
0142      */
0143     template< typename VisitorT >
0144     result_type operator() (attribute_value const& attr, VisitorT visitor) const
0145     {
0146         if (!!attr)
0147         {
0148             static_type_dispatcher< value_type > disp(visitor);
0149             if (attr.dispatch(disp) || fallback_policy::apply_default(visitor))
0150             {
0151                 return visitation_result::ok;
0152             }
0153             else
0154             {
0155                 fallback_policy::on_invalid_type(attr.get_type());
0156                 return visitation_result::value_has_invalid_type;
0157             }
0158         }
0159 
0160         if (fallback_policy::apply_default(visitor))
0161             return visitation_result::ok;
0162 
0163         fallback_policy::on_missing_value();
0164         return visitation_result::value_not_found;
0165     }
0166 
0167     /*!
0168      * Visitation operator. Looks for an attribute value with the specified name
0169      * and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
0170      * the value is passed to \a visitor.
0171      *
0172      * \param name Attribute value name.
0173      * \param attrs A set of attribute values in which to look for the specified attribute value.
0174      * \param visitor A receiving function object to pass the attribute value to.
0175      * \return The result of visitation.
0176      */
0177     template< typename VisitorT >
0178     result_type operator() (attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor) const
0179     {
0180         try
0181         {
0182             attribute_value_set::const_iterator it = attrs.find(name);
0183             if (it != attrs.end())
0184                 return operator() (it->second, visitor);
0185             else
0186                 return operator() (attribute_value(), visitor);
0187         }
0188         catch (exception& e)
0189         {
0190             // Attach the attribute name to the exception
0191             boost::log::aux::attach_attribute_name_info(e, name);
0192             throw;
0193         }
0194     }
0195 
0196     /*!
0197      * Visitation operator. Looks for an attribute value with the specified name
0198      * and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
0199      * the value is passed to \a visitor.
0200      *
0201      * \param name Attribute value name.
0202      * \param rec A log record. The attribute value will be sought among those associated with the record.
0203      * \param visitor A receiving function object to pass the attribute value to.
0204      * \return The result of visitation.
0205      */
0206     template< typename VisitorT >
0207     result_type operator() (attribute_name const& name, record const& rec, VisitorT visitor) const
0208     {
0209         return operator() (name, rec.attribute_values(), visitor);
0210     }
0211 
0212     /*!
0213      * Visitation operator. Looks for an attribute value with the specified name
0214      * and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
0215      * the value is passed to \a visitor.
0216      *
0217      * \param name Attribute value name.
0218      * \param rec A log record view. The attribute value will be sought among those associated with the record.
0219      * \param visitor A receiving function object to pass the attribute value to.
0220      * \return The result of visitation.
0221      */
0222     template< typename VisitorT >
0223     result_type operator() (attribute_name const& name, record_view const& rec, VisitorT visitor) const
0224     {
0225         return operator() (name, rec.attribute_values(), visitor);
0226     }
0227 
0228     /*!
0229      * \returns Fallback policy
0230      */
0231     fallback_policy const& get_fallback_policy() const
0232     {
0233         return *static_cast< fallback_policy const* >(this);
0234     }
0235 };
0236 
0237 /*!
0238  * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
0239  * type or set of possible types of the attribute value to be visited.
0240  *
0241  * \param name The name of the attribute value to visit.
0242  * \param attrs A set of attribute values in which to look for the specified attribute value.
0243  * \param visitor A receiving function object to pass the attribute value to.
0244  * \return The result of visitation.
0245  */
0246 template< typename T, typename VisitorT >
0247 inline visitation_result
0248 visit(attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor)
0249 {
0250     value_visitor_invoker< T > invoker;
0251     return invoker(name, attrs, visitor);
0252 }
0253 
0254 /*!
0255  * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
0256  * type or set of possible types of the attribute value to be visited.
0257  *
0258  * \param name The name of the attribute value to visit.
0259  * \param rec A log record. The attribute value will be sought among those associated with the record.
0260  * \param visitor A receiving function object to pass the attribute value to.
0261  * \return The result of visitation.
0262  */
0263 template< typename T, typename VisitorT >
0264 inline visitation_result
0265 visit(attribute_name const& name, record const& rec, VisitorT visitor)
0266 {
0267     value_visitor_invoker< T > invoker;
0268     return invoker(name, rec, visitor);
0269 }
0270 
0271 /*!
0272  * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
0273  * type or set of possible types of the attribute value to be visited.
0274  *
0275  * \param name The name of the attribute value to visit.
0276  * \param rec A log record view. The attribute value will be sought among those associated with the record.
0277  * \param visitor A receiving function object to pass the attribute value to.
0278  * \return The result of visitation.
0279  */
0280 template< typename T, typename VisitorT >
0281 inline visitation_result
0282 visit(attribute_name const& name, record_view const& rec, VisitorT visitor)
0283 {
0284     value_visitor_invoker< T > invoker;
0285     return invoker(name, rec, visitor);
0286 }
0287 
0288 /*!
0289  * The function applies a visitor to an attribute value. The user has to explicitly specify the
0290  * type or set of possible types of the attribute value to be visited.
0291  *
0292  * \param value The attribute value to visit.
0293  * \param visitor A receiving function object to pass the attribute value to.
0294  * \return The result of visitation.
0295  */
0296 template< typename T, typename VisitorT >
0297 inline visitation_result
0298 visit(attribute_value const& value, VisitorT visitor)
0299 {
0300     value_visitor_invoker< T > invoker;
0301     return invoker(value, visitor);
0302 }
0303 
0304 /*!
0305  * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
0306  * type or set of possible types of the attribute value to be visited.
0307  *
0308  * \param keyword The keyword of the attribute value to visit.
0309  * \param attrs A set of attribute values in which to look for the specified attribute value.
0310  * \param visitor A receiving function object to pass the attribute value to.
0311  * \return The result of visitation.
0312  */
0313 template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
0314 inline visitation_result
0315 visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs, VisitorT visitor)
0316 {
0317     value_visitor_invoker< typename DescriptorT::value_type > invoker;
0318     return invoker(keyword.get_name(), attrs, visitor);
0319 }
0320 
0321 /*!
0322  * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
0323  * type or set of possible types of the attribute value to be visited.
0324  *
0325  * \param keyword The keyword of the attribute value to visit.
0326  * \param rec A log record. The attribute value will be sought among those associated with the record.
0327  * \param visitor A receiving function object to pass the attribute value to.
0328  * \return The result of visitation.
0329  */
0330 template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
0331 inline visitation_result
0332 visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec, VisitorT visitor)
0333 {
0334     value_visitor_invoker< typename DescriptorT::value_type > invoker;
0335     return invoker(keyword.get_name(), rec, visitor);
0336 }
0337 
0338 /*!
0339  * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
0340  * type or set of possible types of the attribute value to be visited.
0341  *
0342  * \param keyword The keyword of the attribute value to visit.
0343  * \param rec A log record view. The attribute value will be sought among those associated with the record.
0344  * \param visitor A receiving function object to pass the attribute value to.
0345  * \return The result of visitation.
0346  */
0347 template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
0348 inline visitation_result
0349 visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec, VisitorT visitor)
0350 {
0351     value_visitor_invoker< typename DescriptorT::value_type > invoker;
0352     return invoker(keyword.get_name(), rec, visitor);
0353 }
0354 
0355 
0356 #if !defined(BOOST_LOG_DOXYGEN_PASS)
0357 
0358 template< typename T, typename VisitorT >
0359 inline visitation_result attribute_value::visit(VisitorT visitor) const
0360 {
0361     return boost::log::visit< T >(*this, visitor);
0362 }
0363 
0364 #endif // !defined(BOOST_LOG_DOXYGEN_PASS)
0365 
0366 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0367 
0368 } // namespace boost
0369 
0370 #include <boost/log/detail/footer.hpp>
0371 
0372 #endif // BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_