Back to home page

EIC code displayed by LXR

 
 

    


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

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   record_ordering.hpp
0009  * \author Andrey Semashev
0010  * \date   23.08.2009
0011  *
0012  * This header contains ordering predicates for logging records.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_RECORD_ORDERING_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_RECORD_ORDERING_HPP_INCLUDED_
0017 
0018 #include <boost/core/enable_if.hpp>
0019 #include <boost/type_traits/is_same.hpp>
0020 #include <boost/log/detail/config.hpp>
0021 #include <boost/log/detail/function_traits.hpp>
0022 #include <boost/log/core/record_view.hpp>
0023 #include <boost/log/attributes/attribute_name.hpp>
0024 #include <boost/log/attributes/attribute_value.hpp>
0025 #include <boost/log/attributes/value_visitation.hpp>
0026 #include <boost/log/utility/functional/logical.hpp>
0027 #include <boost/log/utility/functional/nop.hpp>
0028 #include <boost/log/detail/header.hpp>
0029 
0030 #ifdef BOOST_HAS_PRAGMA_ONCE
0031 #pragma once
0032 #endif
0033 
0034 namespace boost {
0035 
0036 BOOST_LOG_OPEN_NAMESPACE
0037 
0038 /*!
0039  * \brief Ordering predicate, based on opaque pointers to the record view implementation data
0040  *
0041  * Since record views only refer to a shared implementation data, this predicate is able to order the views
0042  * by comparing the pointers to the data. Therefore two views are considered to be equivalent if they
0043  * refer to the same implementation data. Otherwise it is not specified whether one record is ordered before
0044  * the other until the predicate is applied. Note that the ordering may change every time the application runs.
0045  *
0046  * This kind of ordering may be useful if log records are to be stored in an associative
0047  * container with as least performance overhead as possible, when the particular order is not important.
0048  *
0049  * The \c FunT template argument is the predicate that is used to actually compare pointers. It should be
0050  * able to compare <tt>const void*</tt> pointers. The compared pointers may refer to distinct memory regions,
0051  * the pointers must not be interpreted in any way.
0052  */
0053 template< typename FunT = less >
0054 class abstract_ordering :
0055     private FunT
0056 {
0057 public:
0058     //! Result type
0059     typedef bool result_type;
0060 
0061 public:
0062     /*!
0063      * Default constructor. Requires \c FunT to be default constructible.
0064      */
0065     abstract_ordering() : FunT()
0066     {
0067     }
0068     /*!
0069      * Initializing constructor. Constructs \c FunT instance as a copy of the \a fun argument.
0070      */
0071     explicit abstract_ordering(FunT const& fun) : FunT(fun)
0072     {
0073     }
0074 
0075     /*!
0076      * Ordering operator
0077      */
0078     result_type operator() (record_view const& left, record_view const& right) const
0079     {
0080         // We rely on the fact that the attribute_values() method returns a reference to the object in the record implementation,
0081         // so we can compare pointers.
0082         return FunT::operator() (static_cast< const void* >(&left.attribute_values()), static_cast< const void* >(&right.attribute_values()));
0083     }
0084 };
0085 
0086 /*!
0087  * \brief Ordering predicate, based on attribute values associated with records
0088  *
0089  * This predicate allows to order log records based on values of a specifically named attribute
0090  * associated with them. Two given log records being compared should both have the specified
0091  * attribute value of the specified type to be able to be ordered properly. As a special case,
0092  * if neither of the records have the value, these records are considered equivalent. Otherwise,
0093  * the ordering results are unspecified.
0094  */
0095 template< typename ValueT, typename FunT = less >
0096 class attribute_value_ordering :
0097     private FunT
0098 {
0099 public:
0100     //! Result type
0101     typedef bool result_type;
0102     //! Compared attribute value type
0103     typedef ValueT value_type;
0104 
0105 private:
0106     template< typename LeftT >
0107     struct l2_visitor
0108     {
0109         typedef void result_type;
0110 
0111         l2_visitor(FunT const& fun, LeftT const& left, bool& result) :
0112             m_fun(fun), m_left(left), m_result(result)
0113         {
0114         }
0115 
0116         template< typename RightT >
0117         result_type operator() (RightT const& right) const
0118         {
0119             m_result = m_fun(m_left, right);
0120         }
0121 
0122     private:
0123         FunT const& m_fun;
0124         LeftT const& m_left;
0125         bool& m_result;
0126     };
0127 
0128     struct l1_visitor;
0129     friend struct l1_visitor;
0130     struct l1_visitor
0131     {
0132         typedef void result_type;
0133 
0134         l1_visitor(attribute_value_ordering const& owner, record_view const& right, bool& result) :
0135             m_owner(owner), m_right(right), m_result(result)
0136         {
0137         }
0138 
0139         template< typename LeftT >
0140         result_type operator() (LeftT const& left) const
0141         {
0142             boost::log::visit< value_type >(m_owner.m_name, m_right, l2_visitor< LeftT >(static_cast< FunT const& >(m_owner), left, m_result));
0143         }
0144 
0145     private:
0146         attribute_value_ordering const& m_owner;
0147         record_view const& m_right;
0148         bool& m_result;
0149     };
0150 
0151 private:
0152     //! Attribute value name
0153     const attribute_name m_name;
0154 
0155 public:
0156     /*!
0157      * Initializing constructor.
0158      *
0159      * \param name The attribute value name to be compared
0160      * \param fun The ordering functor
0161      */
0162     explicit attribute_value_ordering(attribute_name const& name, FunT const& fun = FunT()) :
0163         FunT(fun),
0164         m_name(name)
0165     {
0166     }
0167 
0168     /*!
0169      * Ordering operator
0170      */
0171     result_type operator() (record_view const& left, record_view const& right) const
0172     {
0173         bool result = false;
0174         if (!boost::log::visit< value_type >(m_name, left, l1_visitor(*this, right, result)))
0175         {
0176             return !boost::log::visit< value_type >(m_name, right, nop());
0177         }
0178         return result;
0179     }
0180 };
0181 
0182 /*!
0183  * The function constructs a log record ordering predicate
0184  */
0185 template< typename ValueT, typename FunT >
0186 inline attribute_value_ordering< ValueT, FunT > make_attr_ordering(attribute_name const& name, FunT const& fun)
0187 {
0188     typedef attribute_value_ordering< ValueT, FunT > ordering_t;
0189     return ordering_t(name, fun);
0190 }
0191 
0192 #if !defined(BOOST_LOG_NO_FUNCTION_TRAITS)
0193 
0194 namespace aux {
0195 
0196     //! An ordering predicate constructor that uses SFINAE to disable invalid instantiations
0197     template<
0198         typename FunT,
0199         typename ArityCheckT = typename boost::enable_if_c< aux::arity_of< FunT >::value == 2 >::type,
0200         typename Arg1T = typename aux::first_argument_type_of< FunT >::type,
0201         typename Arg2T = typename aux::second_argument_type_of< FunT >::type,
0202         typename ArgsCheckT = typename boost::enable_if_c< is_same< Arg1T, Arg2T >::value >::type
0203     >
0204     struct make_attr_ordering_type
0205     {
0206         typedef attribute_value_ordering< Arg1T, FunT > type;
0207     };
0208 
0209 } // namespace aux
0210 
0211 /*!
0212  * The function constructs a log record ordering predicate
0213  */
0214 template< typename FunT >
0215 inline typename aux::make_attr_ordering_type< FunT >::type make_attr_ordering(attribute_name const& name, FunT const& fun)
0216 {
0217     typedef typename aux::make_attr_ordering_type< FunT >::type ordering_t;
0218     return ordering_t(name, fun);
0219 }
0220 
0221 #endif // BOOST_LOG_NO_FUNCTION_TRAITS
0222 
0223 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0224 
0225 } // namespace boost
0226 
0227 #include <boost/log/detail/footer.hpp>
0228 
0229 #endif // BOOST_LOG_UTILITY_RECORD_ORDERING_HPP_INCLUDED_