File indexing completed on 2025-01-18 09:39:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
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
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
0096 template< typename T, typename TagT >
0097 class singular_ref
0098 {
0099 public:
0100
0101 typedef T value_type;
0102
0103 typedef TagT tag_type;
0104
0105 protected:
0106
0107 typedef singular_ref_compatibility_traits compatibility_traits;
0108
0109 protected:
0110
0111 const value_type* m_ptr;
0112
0113 protected:
0114
0115 BOOST_CONSTEXPR singular_ref() BOOST_NOEXCEPT : m_ptr(NULL)
0116 {
0117 }
0118
0119
0120 explicit singular_ref(const value_type* p) BOOST_NOEXCEPT : m_ptr(p)
0121 {
0122 }
0123
0124 public:
0125
0126 const value_type* operator-> () const BOOST_NOEXCEPT
0127 {
0128 BOOST_ASSERT(m_ptr != NULL);
0129 return m_ptr;
0130 }
0131
0132
0133 const value_type* get_ptr() const BOOST_NOEXCEPT
0134 {
0135 return m_ptr;
0136 }
0137
0138
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
0146 value_type const& operator* () const BOOST_NOEXCEPT
0147 {
0148 BOOST_ASSERT(m_ptr != NULL);
0149 return *m_ptr;
0150 }
0151
0152
0153 value_type const& get() const BOOST_NOEXCEPT
0154 {
0155 BOOST_ASSERT(m_ptr != NULL);
0156 return *m_ptr;
0157 }
0158
0159
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
0169 void reset() BOOST_NOEXCEPT
0170 {
0171 m_ptr = NULL;
0172 }
0173
0174
0175 static BOOST_CONSTEXPR unsigned int which()
0176 {
0177 return 0u;
0178 }
0179
0180
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
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
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
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
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
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
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
0252 template< typename T, typename TagT >
0253 class variant_ref
0254 {
0255 public:
0256
0257 typedef T value_type;
0258
0259 typedef TagT tag_type;
0260
0261 protected:
0262
0263 typedef variant_ref_compatibility_traits compatibility_traits;
0264
0265 protected:
0266
0267 const void* m_ptr;
0268
0269 unsigned int m_type_idx;
0270
0271 protected:
0272
0273 BOOST_CONSTEXPR variant_ref() BOOST_NOEXCEPT : m_ptr(NULL), m_type_idx(0u)
0274 {
0275 }
0276
0277
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
0285 void reset() BOOST_NOEXCEPT
0286 {
0287 m_ptr = NULL;
0288 m_type_idx = 0;
0289 }
0290
0291
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
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
0311 unsigned int which() const BOOST_NOEXCEPT
0312 {
0313 return m_type_idx;
0314 }
0315
0316
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
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
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
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
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
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 }
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
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
0431 typedef typename aux::value_ref_base< T, TagT >::type base_type;
0432
0433 typedef typename base_type::compatibility_traits compatibility_traits;
0434
0435 public:
0436 #ifndef BOOST_LOG_DOXYGEN_PASS
0437
0438 typedef typename base_type::value_type value_type;
0439 #else
0440
0441 typedef T value_type;
0442
0443 typedef TagT tag_type;
0444 #endif
0445
0446 public:
0447
0448
0449
0450 BOOST_DEFAULTED_FUNCTION(BOOST_CONSTEXPR value_ref(), BOOST_NOEXCEPT {})
0451
0452
0453
0454
0455 template< typename U >
0456 explicit value_ref(U const& val
0457 #ifndef BOOST_LOG_DOXYGEN_PASS
0458
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
0470
0471 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0472
0473
0474
0475
0476 bool operator! () const BOOST_NOEXCEPT
0477 {
0478 return !this->m_ptr;
0479 }
0480
0481
0482
0483
0484 bool empty() const BOOST_NOEXCEPT
0485 {
0486 return !this->m_ptr;
0487 }
0488
0489
0490
0491
0492 void swap(value_ref& that) BOOST_NOEXCEPT
0493 {
0494 base_type::swap(that);
0495 }
0496 };
0497
0498
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
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
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
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
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
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
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
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
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
0646
0647 }
0648
0649 #include <boost/log/detail/footer.hpp>
0650
0651 #endif