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   value_ref.hpp
0009  * \author Andrey Semashev
0010  * \date   27.07.2012
0011  *
0012  * The header contains implementation of a value reference wrapper.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_
0017 
0018 #include <cstddef>
0019 #include <iosfwd>
0020 #include <boost/assert.hpp>
0021 #include <boost/mpl/if.hpp>
0022 #include <boost/mpl/eval_if.hpp>
0023 #include <boost/mpl/is_sequence.hpp>
0024 #include <boost/mpl/front.hpp>
0025 #include <boost/mpl/size.hpp>
0026 #include <boost/mpl/int.hpp>
0027 #include <boost/mpl/and.hpp>
0028 #include <boost/mpl/identity.hpp>
0029 #include <boost/mpl/equal_to.hpp>
0030 #include <boost/mpl/contains.hpp>
0031 #include <boost/mpl/index_of.hpp>
0032 #include <boost/core/explicit_operator_bool.hpp>
0033 #include <boost/core/addressof.hpp>
0034 #include <boost/optional/optional_fwd.hpp>
0035 #include <boost/type_traits/is_void.hpp>
0036 #include <boost/log/detail/config.hpp>
0037 #include <boost/log/detail/parameter_tools.hpp>
0038 #include <boost/log/detail/value_ref_visitation.hpp>
0039 #include <boost/log/detail/sfinae_tools.hpp>
0040 #include <boost/log/utility/formatting_ostream_fwd.hpp>
0041 #include <boost/log/utility/functional/logical.hpp>
0042 #include <boost/log/utility/functional/bind.hpp>
0043 #include <boost/log/utility/functional/bind_output.hpp>
0044 #include <boost/log/utility/functional/bind_to_log.hpp>
0045 #include <boost/log/utility/manipulators/to_log.hpp>
0046 #include <boost/log/utility/value_ref_fwd.hpp>
0047 #include <boost/log/detail/header.hpp>
0048 
0049 #ifdef BOOST_HAS_PRAGMA_ONCE
0050 #pragma once
0051 #endif
0052 
0053 namespace boost {
0054 
0055 BOOST_LOG_OPEN_NAMESPACE
0056 
0057 namespace aux {
0058 
0059 //! The function object applies the function object to the bound visitable object and argument
0060 template< typename VisitableT, typename FunT >
0061 struct vistation_invoker
0062 {
0063     typedef typename FunT::result_type result_type;
0064 
0065     vistation_invoker(VisitableT& visitable, result_type const& def_val) : m_visitable(visitable), m_def_val(def_val)
0066     {
0067     }
0068 
0069     template< typename ArgT >
0070     result_type operator() (ArgT const& arg) const
0071     {
0072         return m_visitable.apply_visitor_or_default(binder1st< FunT, ArgT const& >(FunT(), arg), m_def_val);
0073     }
0074 
0075 private:
0076     VisitableT& m_visitable;
0077     result_type m_def_val;
0078 };
0079 
0080 //! Traits for testing type compatibility with the reference wrapper
0081 struct singular_ref_compatibility_traits
0082 {
0083     template< typename T, typename U >
0084     struct is_compatible
0085     {
0086         BOOST_STATIC_CONSTANT(bool, value = false);
0087     };
0088     template< typename T >
0089     struct is_compatible< T, T >
0090     {
0091         BOOST_STATIC_CONSTANT(bool, value = true);
0092     };
0093 };
0094 
0095 //! Attribute value reference implementation for a single type case
0096 template< typename T, typename TagT >
0097 class singular_ref
0098 {
0099 public:
0100     //! Referenced value type
0101     typedef T value_type;
0102     //! Tag type
0103     typedef TagT tag_type;
0104 
0105 protected:
0106     //! Traits for testing type compatibility with the reference wrapper
0107     typedef singular_ref_compatibility_traits compatibility_traits;
0108 
0109 protected:
0110     //! Pointer to the value
0111     const value_type* m_ptr;
0112 
0113 protected:
0114     //! Default constructor
0115     BOOST_CONSTEXPR singular_ref() BOOST_NOEXCEPT : m_ptr(NULL)
0116     {
0117     }
0118 
0119     //! Initializing constructor
0120     explicit singular_ref(const value_type* p) BOOST_NOEXCEPT : m_ptr(p)
0121     {
0122     }
0123 
0124 public:
0125     //! Returns a pointer to the referred value
0126     const value_type* operator-> () const BOOST_NOEXCEPT
0127     {
0128         BOOST_ASSERT(m_ptr != NULL);
0129         return m_ptr;
0130     }
0131 
0132     //! Returns a pointer to the referred value
0133     const value_type* get_ptr() const BOOST_NOEXCEPT
0134     {
0135         return m_ptr;
0136     }
0137 
0138     //! Returns a pointer to the referred value
0139     template< typename U >
0140     typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, const U* >::type get_ptr() const BOOST_NOEXCEPT
0141     {
0142         return m_ptr;
0143     }
0144 
0145     //! Returns a reference to the value
0146     value_type const& operator* () const BOOST_NOEXCEPT
0147     {
0148         BOOST_ASSERT(m_ptr != NULL);
0149         return *m_ptr;
0150     }
0151 
0152     //! Returns a reference to the value
0153     value_type const& get() const BOOST_NOEXCEPT
0154     {
0155         BOOST_ASSERT(m_ptr != NULL);
0156         return *m_ptr;
0157     }
0158 
0159     //! Returns a reference to the value
0160     template< typename U >
0161     typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, U const& >::type get() const BOOST_NOEXCEPT
0162     {
0163         BOOST_ASSERT(m_ptr != NULL);
0164         return *m_ptr;
0165     }
0166 
0167 
0168     //! Resets the reference
0169     void reset() BOOST_NOEXCEPT
0170     {
0171         m_ptr = NULL;
0172     }
0173 
0174     //! Returns the stored type index
0175     static BOOST_CONSTEXPR unsigned int which()
0176     {
0177         return 0u;
0178     }
0179 
0180     //! Swaps two reference wrappers
0181     void swap(singular_ref& that) BOOST_NOEXCEPT
0182     {
0183         const void* p = m_ptr;
0184         m_ptr = that.m_ptr;
0185         that.m_ptr = p;
0186     }
0187 
0188     //! Applies a visitor function object to the referred value
0189     template< typename VisitorT >
0190     typename VisitorT::result_type apply_visitor(VisitorT visitor) const
0191     {
0192         BOOST_ASSERT(m_ptr != NULL);
0193         return visitor(*m_ptr);
0194     }
0195 
0196     //! Applies a visitor function object to the referred value
0197     template< typename VisitorT >
0198     typename boost::enable_if_c< is_void< typename VisitorT::result_type >::value, bool >::type apply_visitor_optional(VisitorT visitor) const
0199     {
0200         if (m_ptr)
0201         {
0202             visitor(*m_ptr);
0203             return true;
0204         }
0205         else
0206             return false;
0207     }
0208 
0209     //! Applies a visitor function object to the referred value
0210     template< typename VisitorT >
0211     typename boost::disable_if_c< is_void< typename VisitorT::result_type >::value, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const
0212     {
0213         typedef optional< typename VisitorT::result_type > result_type;
0214         if (m_ptr)
0215             return result_type(visitor(*m_ptr));
0216         else
0217             return result_type();
0218     }
0219 
0220     //! Applies a visitor function object to the referred value or returns a default value
0221     template< typename VisitorT, typename DefaultT >
0222     typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const
0223     {
0224         if (m_ptr)
0225             return visitor(*m_ptr);
0226         else
0227             return def_val;
0228     }
0229 
0230     //! Applies a visitor function object to the referred value or returns a default value
0231     template< typename VisitorT, typename DefaultT >
0232     typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const
0233     {
0234         if (m_ptr)
0235             return visitor(*m_ptr);
0236         else
0237             return def_val;
0238     }
0239 };
0240 
0241 //! Traits for testing type compatibility with the reference wrapper
0242 struct variant_ref_compatibility_traits
0243 {
0244     template< typename T, typename U >
0245     struct is_compatible
0246     {
0247         BOOST_STATIC_CONSTANT(bool, value = (mpl::contains< T, U >::type::value));
0248     };
0249 };
0250 
0251 //! Attribute value reference implementation for multiple types case
0252 template< typename T, typename TagT >
0253 class variant_ref
0254 {
0255 public:
0256     //! Referenced value type
0257     typedef T value_type;
0258     //! Tag type
0259     typedef TagT tag_type;
0260 
0261 protected:
0262     //! Traits for testing type compatibility with the reference wrapper
0263     typedef variant_ref_compatibility_traits compatibility_traits;
0264 
0265 protected:
0266     //! Pointer to the value
0267     const void* m_ptr;
0268     //! Type index
0269     unsigned int m_type_idx;
0270 
0271 protected:
0272     //! Default constructor
0273     BOOST_CONSTEXPR variant_ref() BOOST_NOEXCEPT : m_ptr(NULL), m_type_idx(0u)
0274     {
0275     }
0276 
0277     //! Initializing constructor
0278     template< typename U >
0279     explicit variant_ref(const U* p) BOOST_NOEXCEPT : m_ptr(p), m_type_idx(mpl::index_of< value_type, U >::type::value)
0280     {
0281     }
0282 
0283 public:
0284     //! Resets the reference
0285     void reset() BOOST_NOEXCEPT
0286     {
0287         m_ptr = NULL;
0288         m_type_idx = 0;
0289     }
0290 
0291     //! Returns a pointer to the referred value
0292     template< typename U >
0293     typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, const U* >::type get_ptr() const BOOST_NOEXCEPT
0294     {
0295         if (m_type_idx == static_cast< unsigned int >(mpl::index_of< value_type, U >::type::value))
0296             return static_cast< const U* >(m_ptr);
0297         else
0298             return NULL;
0299     }
0300 
0301     //! Returns a reference to the value
0302     template< typename U >
0303     typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, U const& >::type get() const BOOST_NOEXCEPT
0304     {
0305         const U* const p = get_ptr< U >();
0306         BOOST_ASSERT(p != NULL);
0307         return *p;
0308     }
0309 
0310     //! Returns the stored type index
0311     unsigned int which() const BOOST_NOEXCEPT
0312     {
0313         return m_type_idx;
0314     }
0315 
0316     //! Swaps two reference wrappers
0317     void swap(variant_ref& that) BOOST_NOEXCEPT
0318     {
0319         const void* p = m_ptr;
0320         m_ptr = that.m_ptr;
0321         that.m_ptr = p;
0322         unsigned int type_idx = m_type_idx;
0323         m_type_idx = that.m_type_idx;
0324         that.m_type_idx = type_idx;
0325     }
0326 
0327     //! Applies a visitor function object to the referred value
0328     template< typename VisitorT >
0329     typename VisitorT::result_type apply_visitor(VisitorT visitor) const
0330     {
0331         BOOST_ASSERT(m_ptr != NULL);
0332         return do_apply_visitor(visitor);
0333     }
0334 
0335     //! Applies a visitor function object to the referred value
0336     template< typename VisitorT >
0337     typename boost::enable_if_c< is_void< typename VisitorT::result_type >::value, bool >::type apply_visitor_optional(VisitorT visitor) const
0338     {
0339         if (m_ptr)
0340         {
0341             do_apply_visitor(visitor);
0342             return true;
0343         }
0344         else
0345             return false;
0346     }
0347 
0348     //! Applies a visitor function object to the referred value
0349     template< typename VisitorT >
0350     typename boost::disable_if_c< is_void< typename VisitorT::result_type >::value, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const
0351     {
0352         typedef optional< typename VisitorT::result_type > result_type;
0353         if (m_ptr)
0354             return result_type(do_apply_visitor(visitor));
0355         else
0356             return result_type();
0357     }
0358 
0359     //! Applies a visitor function object to the referred value or returns a default value
0360     template< typename VisitorT, typename DefaultT >
0361     typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const
0362     {
0363         if (m_ptr)
0364             return do_apply_visitor(visitor);
0365         else
0366             return def_val;
0367     }
0368 
0369     //! Applies a visitor function object to the referred value or returns a default value
0370     template< typename VisitorT, typename DefaultT >
0371     typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const
0372     {
0373         if (m_ptr)
0374             return do_apply_visitor(visitor);
0375         else
0376             return def_val;
0377     }
0378 
0379 private:
0380     template< typename VisitorT >
0381     typename VisitorT::result_type do_apply_visitor(VisitorT& visitor) const
0382     {
0383         BOOST_ASSERT(m_type_idx < static_cast< unsigned int >(mpl::size< value_type >::value));
0384         return apply_visitor_dispatch< value_type, VisitorT >::call(m_ptr, m_type_idx, visitor);
0385     }
0386 };
0387 
0388 template< typename T, typename TagT >
0389 struct value_ref_base
0390 {
0391     typedef typename mpl::eval_if<
0392         mpl::and_< mpl::is_sequence< T >, mpl::equal_to< mpl::size< T >, mpl::int_< 1 > > >,
0393         mpl::front< T >,
0394         mpl::identity< T >
0395     >::type value_type;
0396 
0397     typedef typename mpl::if_<
0398         mpl::is_sequence< value_type >,
0399         variant_ref< value_type, TagT >,
0400         singular_ref< value_type, TagT >
0401     >::type type;
0402 };
0403 
0404 } // namespace aux
0405 
0406 /*!
0407  * \brief Reference wrapper for a stored attribute value.
0408  *
0409  * The \c value_ref class template provides access to the stored attribute value. It is not a traditional reference wrapper
0410  * since it may be empty (i.e. refer to no value at all) and it can also refer to values of different types. Therefore its
0411  * interface and behavior combines features of Boost.Ref, Boost.Optional and Boost.Variant, depending on the use case.
0412  *
0413  * The template parameter \c T can be a single type or an MPL sequence of possible types being referred. The reference wrapper
0414  * will act as either an optional reference or an optional variant of references to the specified types. In any case, the
0415  * referred values will not be modifiable (i.e. \c value_ref always models a const reference).
0416  *
0417  * Template parameter \c TagT is optional. It can be used for customizing the operations on this reference wrapper, such as
0418  * putting the referred value to log.
0419  */
0420 template< typename T, typename TagT >
0421 class value_ref :
0422     public aux::value_ref_base< T, TagT >::type
0423 {
0424 #ifndef BOOST_LOG_DOXYGEN_PASS
0425 public:
0426     typedef void _has_basic_formatting_ostream_insert_operator;
0427 #endif
0428 
0429 private:
0430     //! Base implementation type
0431     typedef typename aux::value_ref_base< T, TagT >::type base_type;
0432     //! Traits for testing type compatibility with the reference wrapper
0433     typedef typename base_type::compatibility_traits compatibility_traits;
0434 
0435 public:
0436 #ifndef BOOST_LOG_DOXYGEN_PASS
0437     //! Referenced value type
0438     typedef typename base_type::value_type value_type;
0439 #else
0440     //! Referenced value type
0441     typedef T value_type;
0442     //! Tag type
0443     typedef TagT tag_type;
0444 #endif
0445 
0446 public:
0447     /*!
0448      * Default constructor. Creates a reference wrapper that does not refer to a value.
0449      */
0450     BOOST_DEFAULTED_FUNCTION(BOOST_CONSTEXPR value_ref(), BOOST_NOEXCEPT {})
0451 
0452     /*!
0453      * Initializing constructor. Creates a reference wrapper that refers to the specified value.
0454      */
0455     template< typename U >
0456     explicit value_ref(U const& val
0457 #ifndef BOOST_LOG_DOXYGEN_PASS
0458 // MSVC-8 can't handle SFINAE in this case properly and often wrongly disables this constructor
0459 #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500
0460         , typename boost::enable_if_c< compatibility_traits::BOOST_NESTED_TEMPLATE is_compatible< value_type, U >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
0461 #endif
0462 #endif
0463     ) BOOST_NOEXCEPT :
0464         base_type(boost::addressof(val))
0465     {
0466     }
0467 
0468     /*!
0469      * The operator verifies if the wrapper refers to a value.
0470      */
0471     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0472 
0473     /*!
0474      * The operator verifies if the wrapper does not refer to a value.
0475      */
0476     bool operator! () const BOOST_NOEXCEPT
0477     {
0478         return !this->m_ptr;
0479     }
0480 
0481     /*!
0482      * \return \c true if the wrapper does not refer to a value.
0483      */
0484     bool empty() const BOOST_NOEXCEPT
0485     {
0486         return !this->m_ptr;
0487     }
0488 
0489     /*!
0490      * Swaps two reference wrappers
0491      */
0492     void swap(value_ref& that) BOOST_NOEXCEPT
0493     {
0494         base_type::swap(that);
0495     }
0496 };
0497 
0498 //! Free swap function
0499 template< typename T, typename TagT >
0500 inline void swap(value_ref< T, TagT >& left, value_ref< T, TagT >& right)
0501 {
0502     left.swap(right);
0503 }
0504 
0505 //! Stream output operator
0506 template< typename CharT, typename TraitsT, typename T, typename TagT >
0507 inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, value_ref< T, TagT > const& val)
0508 {
0509     if (!!val)
0510         val.apply_visitor(boost::log::bind_output(strm));
0511     return strm;
0512 }
0513 
0514 //! Log formatting operator
0515 template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename TagT >
0516 inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, value_ref< T, TagT > const& val)
0517 {
0518     if (!!val)
0519         val.apply_visitor(boost::log::bind_to_log< TagT >(strm));
0520     return strm;
0521 }
0522 
0523 // Equality comparison
0524 template< typename T, typename TagT, typename U >
0525 inline bool operator== (value_ref< T, TagT > const& left, U const& right)
0526 {
0527     return left.apply_visitor_or_default(binder2nd< equal_to, U const& >(equal_to(), right), false);
0528 }
0529 
0530 template< typename U, typename T, typename TagT >
0531 inline bool operator== (U const& left, value_ref< T, TagT > const& right)
0532 {
0533     return right.apply_visitor_or_default(binder1st< equal_to, U const& >(equal_to(), left), false);
0534 }
0535 
0536 template< typename T1, typename TagT1, typename T2, typename TagT2 >
0537 inline bool operator== (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
0538 {
0539     if (!left && !right)
0540         return true;
0541     return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, equal_to >(right, false), false);
0542 }
0543 
0544 // Inequality comparison
0545 template< typename T, typename TagT, typename U >
0546 inline bool operator!= (value_ref< T, TagT > const& left, U const& right)
0547 {
0548     return left.apply_visitor_or_default(binder2nd< not_equal_to, U const& >(not_equal_to(), right), false);
0549 }
0550 
0551 template< typename U, typename T, typename TagT >
0552 inline bool operator!= (U const& left, value_ref< T, TagT > const& right)
0553 {
0554     return right.apply_visitor_or_default(binder1st< not_equal_to, U const& >(not_equal_to(), left), false);
0555 }
0556 
0557 template< typename T1, typename TagT1, typename T2, typename TagT2 >
0558 inline bool operator!= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
0559 {
0560     if (!left && !right)
0561         return false;
0562     return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, not_equal_to >(right, false), false);
0563 }
0564 
0565 // Less than ordering
0566 template< typename T, typename TagT, typename U >
0567 inline bool operator< (value_ref< T, TagT > const& left, U const& right)
0568 {
0569     return left.apply_visitor_or_default(binder2nd< less, U const& >(less(), right), false);
0570 }
0571 
0572 template< typename U, typename T, typename TagT >
0573 inline bool operator< (U const& left, value_ref< T, TagT > const& right)
0574 {
0575     return right.apply_visitor_or_default(binder1st< less, U const& >(less(), left), false);
0576 }
0577 
0578 template< typename T1, typename TagT1, typename T2, typename TagT2 >
0579 inline bool operator< (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
0580 {
0581     return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less >(right, false), false);
0582 }
0583 
0584 // Greater than ordering
0585 template< typename T, typename TagT, typename U >
0586 inline bool operator> (value_ref< T, TagT > const& left, U const& right)
0587 {
0588     return left.apply_visitor_or_default(binder2nd< greater, U const& >(greater(), right), false);
0589 }
0590 
0591 template< typename U, typename T, typename TagT >
0592 inline bool operator> (U const& left, value_ref< T, TagT > const& right)
0593 {
0594     return right.apply_visitor_or_default(binder1st< greater, U const& >(greater(), left), false);
0595 }
0596 
0597 template< typename T1, typename TagT1, typename T2, typename TagT2 >
0598 inline bool operator> (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
0599 {
0600     return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater >(right, false), false);
0601 }
0602 
0603 // Less or equal ordering
0604 template< typename T, typename TagT, typename U >
0605 inline bool operator<= (value_ref< T, TagT > const& left, U const& right)
0606 {
0607     return left.apply_visitor_or_default(binder2nd< less_equal, U const& >(less_equal(), right), false);
0608 }
0609 
0610 template< typename U, typename T, typename TagT >
0611 inline bool operator<= (U const& left, value_ref< T, TagT > const& right)
0612 {
0613     return right.apply_visitor_or_default(binder1st< less_equal, U const& >(less_equal(), left), false);
0614 }
0615 
0616 template< typename T1, typename TagT1, typename T2, typename TagT2 >
0617 inline bool operator<= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
0618 {
0619     if (!left && !right)
0620         return true;
0621     return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less_equal >(right, false), false);
0622 }
0623 
0624 // Greater or equal ordering
0625 template< typename T, typename TagT, typename U >
0626 inline bool operator>= (value_ref< T, TagT > const& left, U const& right)
0627 {
0628     return left.apply_visitor_or_default(binder2nd< greater_equal, U const& >(greater_equal(), right), false);
0629 }
0630 
0631 template< typename U, typename T, typename TagT >
0632 inline bool operator>= (U const& left, value_ref< T, TagT > const& right)
0633 {
0634     return right.apply_visitor_or_default(binder1st< greater_equal, U const& >(greater_equal(), left), false);
0635 }
0636 
0637 template< typename T1, typename TagT1, typename T2, typename TagT2 >
0638 inline bool operator>= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
0639 {
0640     if (!left && !right)
0641         return true;
0642     return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater_equal >(right, false), false);
0643 }
0644 
0645 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0646 
0647 } // namespace boost
0648 
0649 #include <boost/log/detail/footer.hpp>
0650 
0651 #endif // BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_