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 value_ref.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 27.07.2012 Chris@16: * Chris@16: * The header contains implementation of a value reference wrapper. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_UTILITY_VALUE_REF_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: #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 aux { Chris@16: Chris@16: //! The function object applies the function object to the bound visitable object and argument Chris@16: template< typename VisitableT, typename FunT > Chris@16: struct vistation_invoker Chris@16: { Chris@16: typedef typename FunT::result_type result_type; Chris@16: Chris@16: vistation_invoker(VisitableT& visitable, result_type const& def_val) : m_visitable(visitable), m_def_val(def_val) Chris@16: { Chris@16: } Chris@16: Chris@16: template< typename ArgT > Chris@16: result_type operator() (ArgT const& arg) const Chris@16: { Chris@16: return m_visitable.apply_visitor_or_default(binder1st< FunT, ArgT const& >(FunT(), arg), m_def_val); Chris@16: } Chris@16: Chris@16: private: Chris@16: VisitableT& m_visitable; Chris@16: result_type m_def_val; Chris@16: }; Chris@16: Chris@16: //! Attribute value reference implementation for a single type case Chris@16: template< typename T, typename TagT > Chris@16: class singular_ref Chris@16: { Chris@16: public: Chris@16: //! Referenced value type Chris@16: typedef T value_type; Chris@16: //! Tag type Chris@16: typedef TagT tag_type; Chris@16: Chris@16: protected: Chris@16: //! The metafunction tests if the type is compatible with the reference wrapper Chris@16: #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) Chris@16: template< typename U > Chris@16: using is_compatible = is_same< U, value_type >; Chris@16: #else Chris@16: template< typename U > Chris@16: struct is_compatible : Chris@16: public is_same< U, value_type > Chris@16: { Chris@16: }; Chris@16: #endif Chris@16: Chris@16: protected: Chris@16: //! Pointer to the value Chris@16: const value_type* m_ptr; Chris@16: Chris@16: protected: Chris@16: //! Default constructor Chris@16: singular_ref() BOOST_NOEXCEPT : m_ptr(NULL) Chris@16: { Chris@16: } Chris@16: Chris@16: //! Initializing constructor Chris@16: explicit singular_ref(const value_type* p) BOOST_NOEXCEPT : m_ptr(p) Chris@16: { Chris@16: } Chris@16: Chris@16: public: Chris@16: //! Returns a pointer to the referred value Chris@16: const value_type* operator-> () const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_ptr != NULL); Chris@16: return m_ptr; Chris@16: } Chris@16: Chris@16: //! Returns a pointer to the referred value Chris@16: const value_type* get_ptr() const BOOST_NOEXCEPT Chris@16: { Chris@16: return m_ptr; Chris@16: } Chris@16: Chris@16: //! Returns a pointer to the referred value Chris@16: template< typename U > Chris@16: typename enable_if< is_compatible< U >, const U* >::type get_ptr() const BOOST_NOEXCEPT Chris@16: { Chris@16: return m_ptr; Chris@16: } Chris@16: Chris@16: //! Returns a reference to the value Chris@16: value_type const& operator* () const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_ptr != NULL); Chris@16: return *m_ptr; Chris@16: } Chris@16: Chris@16: //! Returns a reference to the value Chris@16: value_type const& get() const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_ptr != NULL); Chris@16: return *m_ptr; Chris@16: } Chris@16: Chris@16: //! Returns a reference to the value Chris@16: template< typename U > Chris@16: typename enable_if< is_compatible< U >, U const& >::type get() const BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_ASSERT(m_ptr != NULL); Chris@16: return *m_ptr; Chris@16: } Chris@16: Chris@16: Chris@16: //! Resets the reference Chris@16: void reset() BOOST_NOEXCEPT Chris@16: { Chris@16: m_ptr = NULL; Chris@16: } Chris@16: Chris@16: //! Returns the stored type index Chris@16: static BOOST_CONSTEXPR unsigned int which() Chris@16: { Chris@16: return 0u; Chris@16: } Chris@16: Chris@16: //! Swaps two reference wrappers Chris@16: void swap(singular_ref& that) BOOST_NOEXCEPT Chris@16: { Chris@16: const void* p = m_ptr; Chris@16: m_ptr = that.m_ptr; Chris@16: that.m_ptr = p; Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value Chris@16: template< typename VisitorT > Chris@16: typename VisitorT::result_type apply_visitor(VisitorT visitor) const Chris@16: { Chris@16: BOOST_ASSERT(m_ptr != NULL); Chris@16: return visitor(*m_ptr); Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value Chris@16: template< typename VisitorT > Chris@16: typename enable_if< is_void< typename VisitorT::result_type >, bool >::type apply_visitor_optional(VisitorT visitor) const Chris@16: { Chris@16: if (m_ptr) Chris@16: { Chris@16: visitor(*m_ptr); Chris@16: return true; Chris@16: } Chris@16: else Chris@16: return false; Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value Chris@16: template< typename VisitorT > Chris@16: typename disable_if< is_void< typename VisitorT::result_type >, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const Chris@16: { Chris@16: typedef optional< typename VisitorT::result_type > result_type; Chris@16: if (m_ptr) Chris@16: return result_type(visitor(*m_ptr)); Chris@16: else Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value or returns a default value Chris@16: template< typename VisitorT, typename DefaultT > Chris@16: typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const Chris@16: { Chris@16: if (m_ptr) Chris@16: return visitor(*m_ptr); Chris@16: else Chris@16: return def_val; Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value or returns a default value Chris@16: template< typename VisitorT, typename DefaultT > Chris@16: typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const Chris@16: { Chris@16: if (m_ptr) Chris@16: return visitor(*m_ptr); Chris@16: else Chris@16: return def_val; Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Attribute value reference implementation for multiple types case Chris@16: template< typename T, typename TagT > Chris@16: class variant_ref Chris@16: { Chris@16: public: Chris@16: //! Referenced value type Chris@16: typedef T value_type; Chris@16: //! Tag type Chris@16: typedef TagT tag_type; Chris@16: Chris@16: protected: Chris@16: //! The metafunction tests if the type is compatible with the reference wrapper Chris@16: #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) Chris@16: template< typename U > Chris@16: using is_compatible = mpl::contains< value_type, U >; Chris@16: #else Chris@16: template< typename U > Chris@16: struct is_compatible : Chris@16: public mpl::contains< value_type, U > Chris@16: { Chris@16: }; Chris@16: #endif Chris@16: Chris@16: protected: Chris@16: //! Pointer to the value Chris@16: const void* m_ptr; Chris@16: //! Type index Chris@16: unsigned int m_type_idx; Chris@16: Chris@16: protected: Chris@16: //! Default constructor Chris@16: variant_ref() BOOST_NOEXCEPT : m_ptr(NULL), m_type_idx(0) Chris@16: { Chris@16: } Chris@16: Chris@16: //! Initializing constructor Chris@16: template< typename U > Chris@16: explicit variant_ref(const U* p) BOOST_NOEXCEPT : m_ptr(p), m_type_idx(mpl::index_of< value_type, U >::type::value) Chris@16: { Chris@16: } Chris@16: Chris@16: public: Chris@16: //! Resets the reference Chris@16: void reset() BOOST_NOEXCEPT Chris@16: { Chris@16: m_ptr = NULL; Chris@16: m_type_idx = 0; Chris@16: } Chris@16: Chris@16: //! Returns a pointer to the referred value Chris@16: template< typename U > Chris@16: typename enable_if< is_compatible< U >, const U* >::type get_ptr() const BOOST_NOEXCEPT Chris@16: { Chris@16: if (m_type_idx == static_cast< unsigned int >(mpl::index_of< value_type, U >::type::value)) Chris@16: return static_cast< const U* >(m_ptr); Chris@16: else Chris@16: return NULL; Chris@16: } Chris@16: Chris@16: //! Returns a reference to the value Chris@16: template< typename U > Chris@16: typename enable_if< is_compatible< U >, U const& >::type get() const BOOST_NOEXCEPT Chris@16: { Chris@16: const U* const p = get_ptr< U >(); Chris@16: BOOST_ASSERT(p != NULL); Chris@16: return *p; Chris@16: } Chris@16: Chris@16: //! Returns the stored type index Chris@16: unsigned int which() const BOOST_NOEXCEPT Chris@16: { Chris@16: return m_type_idx; Chris@16: } Chris@16: Chris@16: //! Swaps two reference wrappers Chris@16: void swap(variant_ref& that) BOOST_NOEXCEPT Chris@16: { Chris@16: const void* p = m_ptr; Chris@16: m_ptr = that.m_ptr; Chris@16: that.m_ptr = p; Chris@16: unsigned int type_idx = m_type_idx; Chris@16: m_type_idx = that.m_type_idx; Chris@16: that.m_type_idx = type_idx; Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value Chris@16: template< typename VisitorT > Chris@16: typename VisitorT::result_type apply_visitor(VisitorT visitor) const Chris@16: { Chris@16: BOOST_ASSERT(m_ptr != NULL); Chris@16: return do_apply_visitor(visitor); Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value Chris@16: template< typename VisitorT > Chris@16: typename enable_if< is_void< typename VisitorT::result_type >, bool >::type apply_visitor_optional(VisitorT visitor) const Chris@16: { Chris@16: if (m_ptr) Chris@16: { Chris@16: do_apply_visitor(visitor); Chris@16: return true; Chris@16: } Chris@16: else Chris@16: return false; Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value Chris@16: template< typename VisitorT > Chris@16: typename disable_if< is_void< typename VisitorT::result_type >, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const Chris@16: { Chris@16: typedef optional< typename VisitorT::result_type > result_type; Chris@16: if (m_ptr) Chris@16: return result_type(do_apply_visitor(visitor)); Chris@16: else Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value or returns a default value Chris@16: template< typename VisitorT, typename DefaultT > Chris@16: typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const Chris@16: { Chris@16: if (m_ptr) Chris@16: return do_apply_visitor(visitor); Chris@16: else Chris@16: return def_val; Chris@16: } Chris@16: Chris@16: //! Applies a visitor function object to the referred value or returns a default value Chris@16: template< typename VisitorT, typename DefaultT > Chris@16: typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const Chris@16: { Chris@16: if (m_ptr) Chris@16: return do_apply_visitor(visitor); Chris@16: else Chris@16: return def_val; Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename VisitorT > Chris@16: typename VisitorT::result_type do_apply_visitor(VisitorT& visitor) const Chris@16: { Chris@16: BOOST_ASSERT(m_type_idx < static_cast< unsigned int >(mpl::size< value_type >::value)); Chris@16: return apply_visitor_dispatch< value_type, VisitorT >::call(m_ptr, m_type_idx, visitor); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< typename T, typename TagT > Chris@16: struct value_ref_base Chris@16: { Chris@16: typedef typename mpl::eval_if< Chris@16: mpl::and_< mpl::is_sequence< T >, mpl::equal_to< mpl::size< T >, mpl::int_< 1 > > >, Chris@16: mpl::front< T >, Chris@16: mpl::identity< T > Chris@16: >::type value_type; Chris@16: Chris@16: typedef typename mpl::if_< Chris@16: mpl::is_sequence< value_type >, Chris@16: variant_ref< value_type, TagT >, Chris@16: singular_ref< value_type, TagT > Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: /*! Chris@16: * \brief Reference wrapper for a stored attribute value. Chris@16: * Chris@16: * The \c value_ref class template provides access to the stored attribute value. It is not a traditional reference wrapper Chris@16: * 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 Chris@16: * interface and behavior combines features of Boost.Ref, Boost.Optional and Boost.Variant, depending on the use case. Chris@16: * Chris@16: * The template parameter \c T can be a single type or an MPL sequence of possible types being referred. The reference wrapper Chris@16: * will act as either an optional reference or an optional variant of references to the specified types. In any case, the Chris@16: * referred values will not be modifiable (i.e. \c value_ref always models a const reference). Chris@16: * Chris@16: * Template parameter \c TagT is optional. It can be used for customizing the operations on this reference wrapper, such as Chris@16: * putting the referred value to log. Chris@16: */ Chris@16: template< typename T, typename TagT > Chris@16: class value_ref : Chris@16: public aux::value_ref_base< T, TagT >::type Chris@16: { Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: public: Chris@16: typedef void _has_basic_formatting_ostream_insert_operator; Chris@16: #endif Chris@16: Chris@16: private: Chris@16: //! Base implementation type Chris@16: typedef typename aux::value_ref_base< T, TagT >::type base_type; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor. Creates a reference wrapper that does not refer to a value. Chris@16: */ Chris@16: BOOST_DEFAULTED_FUNCTION(value_ref(), BOOST_NOEXCEPT {}) Chris@16: Chris@16: /*! Chris@16: * Copy constructor. Chris@16: */ Chris@16: BOOST_DEFAULTED_FUNCTION(value_ref(value_ref const& that), BOOST_NOEXCEPT : base_type(static_cast< base_type const& >(that)) {}) Chris@16: Chris@16: /*! Chris@16: * Initializing constructor. Creates a reference wrapper that refers to the specified value. Chris@16: */ Chris@16: template< typename U > Chris@16: explicit value_ref(U const& val, typename enable_if< typename base_type::BOOST_NESTED_TEMPLATE is_compatible< U >, int >::type = 0) BOOST_NOEXCEPT : Chris@16: base_type(boost::addressof(val)) Chris@16: { Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The operator verifies if the wrapper refers to a value. Chris@16: */ Chris@101: BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() Chris@16: Chris@16: /*! Chris@16: * The operator verifies if the wrapper does not refer to a value. Chris@16: */ Chris@16: bool operator! () const BOOST_NOEXCEPT Chris@16: { Chris@16: return !this->m_ptr; Chris@16: } Chris@16: Chris@16: /*! Chris@16: * \return \c true if the wrapper does not refer to a value. Chris@16: */ Chris@16: bool empty() const BOOST_NOEXCEPT Chris@16: { Chris@16: return !this->m_ptr; Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Swaps two reference wrappers Chris@16: */ Chris@16: void swap(value_ref& that) BOOST_NOEXCEPT Chris@16: { Chris@16: base_type::swap(that); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Free swap function Chris@16: template< typename T, typename TagT > Chris@16: inline void swap(value_ref< T, TagT >& left, value_ref< T, TagT >& right) Chris@16: { Chris@16: left.swap(right); Chris@16: } Chris@16: Chris@16: //! Stream output operator Chris@16: template< typename CharT, typename TraitsT, typename T, typename TagT > Chris@16: inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, value_ref< T, TagT > const& val) Chris@16: { Chris@16: if (!!val) Chris@16: val.apply_visitor(boost::log::bind_output(strm)); Chris@16: return strm; Chris@16: } Chris@16: Chris@16: //! Log formatting operator Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename TagT > Chris@16: inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, value_ref< T, TagT > const& val) Chris@16: { Chris@16: if (!!val) Chris@16: val.apply_visitor(boost::log::bind_to_log< TagT >(strm)); Chris@16: return strm; Chris@16: } Chris@16: Chris@16: // Equality comparison Chris@16: template< typename T, typename TagT, typename U > Chris@16: inline bool operator== (value_ref< T, TagT > const& left, U const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(binder2nd< equal_to, U const& >(equal_to(), right), false); Chris@16: } Chris@16: Chris@16: template< typename U, typename T, typename TagT > Chris@16: inline bool operator== (U const& left, value_ref< T, TagT > const& right) Chris@16: { Chris@16: return right.apply_visitor_or_default(binder1st< equal_to, U const& >(equal_to(), left), false); Chris@16: } Chris@16: Chris@16: template< typename T1, typename TagT1, typename T2, typename TagT2 > Chris@16: inline bool operator== (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) Chris@16: { Chris@16: if (!left && !right) Chris@16: return true; Chris@16: return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, equal_to >(right, false), false); Chris@16: } Chris@16: Chris@16: // Inequality comparison Chris@16: template< typename T, typename TagT, typename U > Chris@16: inline bool operator!= (value_ref< T, TagT > const& left, U const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(binder2nd< not_equal_to, U const& >(not_equal_to(), right), false); Chris@16: } Chris@16: Chris@16: template< typename U, typename T, typename TagT > Chris@16: inline bool operator!= (U const& left, value_ref< T, TagT > const& right) Chris@16: { Chris@16: return right.apply_visitor_or_default(binder1st< not_equal_to, U const& >(not_equal_to(), left), false); Chris@16: } Chris@16: Chris@16: template< typename T1, typename TagT1, typename T2, typename TagT2 > Chris@16: inline bool operator!= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) Chris@16: { Chris@16: if (!left && !right) Chris@16: return false; Chris@16: return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, not_equal_to >(right, false), false); Chris@16: } Chris@16: Chris@16: // Less than ordering Chris@16: template< typename T, typename TagT, typename U > Chris@16: inline bool operator< (value_ref< T, TagT > const& left, U const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(binder2nd< less, U const& >(less(), right), false); Chris@16: } Chris@16: Chris@16: template< typename U, typename T, typename TagT > Chris@16: inline bool operator< (U const& left, value_ref< T, TagT > const& right) Chris@16: { Chris@16: return right.apply_visitor_or_default(binder1st< less, U const& >(less(), left), false); Chris@16: } Chris@16: Chris@16: template< typename T1, typename TagT1, typename T2, typename TagT2 > Chris@16: inline bool operator< (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less >(right, false), false); Chris@16: } Chris@16: Chris@16: // Greater than ordering Chris@16: template< typename T, typename TagT, typename U > Chris@16: inline bool operator> (value_ref< T, TagT > const& left, U const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(binder2nd< greater, U const& >(greater(), right), false); Chris@16: } Chris@16: Chris@16: template< typename U, typename T, typename TagT > Chris@16: inline bool operator> (U const& left, value_ref< T, TagT > const& right) Chris@16: { Chris@16: return right.apply_visitor_or_default(binder1st< greater, U const& >(greater(), left), false); Chris@16: } Chris@16: Chris@16: template< typename T1, typename TagT1, typename T2, typename TagT2 > Chris@16: inline bool operator> (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater >(right, false), false); Chris@16: } Chris@16: Chris@16: // Less or equal ordering Chris@16: template< typename T, typename TagT, typename U > Chris@16: inline bool operator<= (value_ref< T, TagT > const& left, U const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(binder2nd< less_equal, U const& >(less_equal(), right), false); Chris@16: } Chris@16: Chris@16: template< typename U, typename T, typename TagT > Chris@16: inline bool operator<= (U const& left, value_ref< T, TagT > const& right) Chris@16: { Chris@16: return right.apply_visitor_or_default(binder1st< less_equal, U const& >(less_equal(), left), false); Chris@16: } Chris@16: Chris@16: template< typename T1, typename TagT1, typename T2, typename TagT2 > Chris@16: inline bool operator<= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) Chris@16: { Chris@16: if (!left && !right) Chris@16: return true; Chris@16: return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less_equal >(right, false), false); Chris@16: } Chris@16: Chris@16: // Greater or equal ordering Chris@16: template< typename T, typename TagT, typename U > Chris@16: inline bool operator>= (value_ref< T, TagT > const& left, U const& right) Chris@16: { Chris@16: return left.apply_visitor_or_default(binder2nd< greater_equal, U const& >(greater_equal(), right), false); Chris@16: } Chris@16: Chris@16: template< typename U, typename T, typename TagT > Chris@16: inline bool operator>= (U const& left, value_ref< T, TagT > const& right) Chris@16: { Chris@16: return right.apply_visitor_or_default(binder1st< greater_equal, U const& >(greater_equal(), left), false); Chris@16: } Chris@16: Chris@16: template< typename T1, typename TagT1, typename T2, typename TagT2 > Chris@16: inline bool operator>= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) Chris@16: { Chris@16: if (!left && !right) Chris@16: return true; Chris@16: return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater_equal >(right, false), false); Chris@16: } Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_