]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Copyright Andrey Semashev 2007 - 2015. | |
3 | * Distributed under the Boost Software License, Version 1.0. | |
4 | * (See accompanying file LICENSE_1_0.txt or copy at | |
5 | * http://www.boost.org/LICENSE_1_0.txt) | |
6 | */ | |
7 | /*! | |
8 | * \file value_ref.hpp | |
9 | * \author Andrey Semashev | |
10 | * \date 27.07.2012 | |
11 | * | |
12 | * The header contains implementation of a value reference wrapper. | |
13 | */ | |
14 | ||
15 | #ifndef BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_ | |
16 | #define BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_ | |
17 | ||
18 | #include <cstddef> | |
19 | #include <iosfwd> | |
20 | #include <boost/assert.hpp> | |
21 | #include <boost/mpl/if.hpp> | |
22 | #include <boost/mpl/eval_if.hpp> | |
23 | #include <boost/mpl/is_sequence.hpp> | |
24 | #include <boost/mpl/front.hpp> | |
25 | #include <boost/mpl/size.hpp> | |
26 | #include <boost/mpl/int.hpp> | |
27 | #include <boost/mpl/and.hpp> | |
28 | #include <boost/mpl/identity.hpp> | |
29 | #include <boost/mpl/equal_to.hpp> | |
30 | #include <boost/mpl/contains.hpp> | |
31 | #include <boost/mpl/index_of.hpp> | |
32 | #include <boost/core/explicit_operator_bool.hpp> | |
33 | #include <boost/core/addressof.hpp> | |
34 | #include <boost/optional/optional_fwd.hpp> | |
35 | #include <boost/type_traits/is_void.hpp> | |
36 | #include <boost/log/detail/config.hpp> | |
37 | #include <boost/log/detail/parameter_tools.hpp> | |
38 | #include <boost/log/detail/value_ref_visitation.hpp> | |
39 | #include <boost/log/detail/sfinae_tools.hpp> | |
40 | #include <boost/log/utility/formatting_ostream_fwd.hpp> | |
41 | #include <boost/log/utility/functional/logical.hpp> | |
42 | #include <boost/log/utility/functional/bind.hpp> | |
43 | #include <boost/log/utility/functional/bind_output.hpp> | |
44 | #include <boost/log/utility/functional/bind_to_log.hpp> | |
45 | #include <boost/log/utility/manipulators/to_log.hpp> | |
46 | #include <boost/log/utility/value_ref_fwd.hpp> | |
47 | #include <boost/log/detail/header.hpp> | |
48 | ||
49 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
50 | #pragma once | |
51 | #endif | |
52 | ||
53 | namespace boost { | |
54 | ||
55 | BOOST_LOG_OPEN_NAMESPACE | |
56 | ||
57 | namespace aux { | |
58 | ||
59 | //! The function object applies the function object to the bound visitable object and argument | |
60 | template< typename VisitableT, typename FunT > | |
61 | struct vistation_invoker | |
62 | { | |
63 | typedef typename FunT::result_type result_type; | |
64 | ||
65 | vistation_invoker(VisitableT& visitable, result_type const& def_val) : m_visitable(visitable), m_def_val(def_val) | |
66 | { | |
67 | } | |
68 | ||
69 | template< typename ArgT > | |
70 | result_type operator() (ArgT const& arg) const | |
71 | { | |
72 | return m_visitable.apply_visitor_or_default(binder1st< FunT, ArgT const& >(FunT(), arg), m_def_val); | |
73 | } | |
74 | ||
75 | private: | |
76 | VisitableT& m_visitable; | |
77 | result_type m_def_val; | |
78 | }; | |
79 | ||
80 | //! Traits for testing type compatibility with the reference wrapper | |
81 | struct singular_ref_compatibility_traits | |
82 | { | |
83 | template< typename T, typename U > | |
84 | struct is_compatible | |
85 | { | |
86 | BOOST_STATIC_CONSTANT(bool, value = false); | |
87 | }; | |
88 | template< typename T > | |
89 | struct is_compatible< T, T > | |
90 | { | |
91 | BOOST_STATIC_CONSTANT(bool, value = true); | |
92 | }; | |
93 | }; | |
94 | ||
95 | //! Attribute value reference implementation for a single type case | |
96 | template< typename T, typename TagT > | |
97 | class singular_ref | |
98 | { | |
99 | public: | |
100 | //! Referenced value type | |
101 | typedef T value_type; | |
102 | //! Tag type | |
103 | typedef TagT tag_type; | |
104 | ||
105 | protected: | |
106 | //! Traits for testing type compatibility with the reference wrapper | |
107 | typedef singular_ref_compatibility_traits compatibility_traits; | |
108 | ||
109 | protected: | |
110 | //! Pointer to the value | |
111 | const value_type* m_ptr; | |
112 | ||
113 | protected: | |
114 | //! Default constructor | |
115 | singular_ref() BOOST_NOEXCEPT : m_ptr(NULL) | |
116 | { | |
117 | } | |
118 | ||
119 | //! Initializing constructor | |
120 | explicit singular_ref(const value_type* p) BOOST_NOEXCEPT : m_ptr(p) | |
121 | { | |
122 | } | |
123 | ||
124 | public: | |
125 | //! Returns a pointer to the referred value | |
126 | const value_type* operator-> () const BOOST_NOEXCEPT | |
127 | { | |
128 | BOOST_ASSERT(m_ptr != NULL); | |
129 | return m_ptr; | |
130 | } | |
131 | ||
132 | //! Returns a pointer to the referred value | |
133 | const value_type* get_ptr() const BOOST_NOEXCEPT | |
134 | { | |
135 | return m_ptr; | |
136 | } | |
137 | ||
138 | //! Returns a pointer to the referred value | |
139 | template< typename U > | |
140 | typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, const U* >::type get_ptr() const BOOST_NOEXCEPT | |
141 | { | |
142 | return m_ptr; | |
143 | } | |
144 | ||
145 | //! Returns a reference to the value | |
146 | value_type const& operator* () const BOOST_NOEXCEPT | |
147 | { | |
148 | BOOST_ASSERT(m_ptr != NULL); | |
149 | return *m_ptr; | |
150 | } | |
151 | ||
152 | //! Returns a reference to the value | |
153 | value_type const& get() const BOOST_NOEXCEPT | |
154 | { | |
155 | BOOST_ASSERT(m_ptr != NULL); | |
156 | return *m_ptr; | |
157 | } | |
158 | ||
159 | //! Returns a reference to the value | |
160 | template< typename U > | |
161 | typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, U const& >::type get() const BOOST_NOEXCEPT | |
162 | { | |
163 | BOOST_ASSERT(m_ptr != NULL); | |
164 | return *m_ptr; | |
165 | } | |
166 | ||
167 | ||
168 | //! Resets the reference | |
169 | void reset() BOOST_NOEXCEPT | |
170 | { | |
171 | m_ptr = NULL; | |
172 | } | |
173 | ||
174 | //! Returns the stored type index | |
175 | static BOOST_CONSTEXPR unsigned int which() | |
176 | { | |
177 | return 0u; | |
178 | } | |
179 | ||
180 | //! Swaps two reference wrappers | |
181 | void swap(singular_ref& that) BOOST_NOEXCEPT | |
182 | { | |
183 | const void* p = m_ptr; | |
184 | m_ptr = that.m_ptr; | |
185 | that.m_ptr = p; | |
186 | } | |
187 | ||
188 | //! Applies a visitor function object to the referred value | |
189 | template< typename VisitorT > | |
190 | typename VisitorT::result_type apply_visitor(VisitorT visitor) const | |
191 | { | |
192 | BOOST_ASSERT(m_ptr != NULL); | |
193 | return visitor(*m_ptr); | |
194 | } | |
195 | ||
196 | //! Applies a visitor function object to the referred value | |
197 | template< typename VisitorT > | |
198 | typename boost::enable_if_c< is_void< typename VisitorT::result_type >::value, bool >::type apply_visitor_optional(VisitorT visitor) const | |
199 | { | |
200 | if (m_ptr) | |
201 | { | |
202 | visitor(*m_ptr); | |
203 | return true; | |
204 | } | |
205 | else | |
206 | return false; | |
207 | } | |
208 | ||
209 | //! Applies a visitor function object to the referred value | |
210 | template< typename VisitorT > | |
211 | typename boost::disable_if_c< is_void< typename VisitorT::result_type >::value, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const | |
212 | { | |
213 | typedef optional< typename VisitorT::result_type > result_type; | |
214 | if (m_ptr) | |
215 | return result_type(visitor(*m_ptr)); | |
216 | else | |
217 | return result_type(); | |
218 | } | |
219 | ||
220 | //! Applies a visitor function object to the referred value or returns a default value | |
221 | template< typename VisitorT, typename DefaultT > | |
222 | typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const | |
223 | { | |
224 | if (m_ptr) | |
225 | return visitor(*m_ptr); | |
226 | else | |
227 | return def_val; | |
228 | } | |
229 | ||
230 | //! Applies a visitor function object to the referred value or returns a default value | |
231 | template< typename VisitorT, typename DefaultT > | |
232 | typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const | |
233 | { | |
234 | if (m_ptr) | |
235 | return visitor(*m_ptr); | |
236 | else | |
237 | return def_val; | |
238 | } | |
239 | }; | |
240 | ||
241 | //! Traits for testing type compatibility with the reference wrapper | |
242 | struct variant_ref_compatibility_traits | |
243 | { | |
244 | template< typename T, typename U > | |
245 | struct is_compatible | |
246 | { | |
247 | BOOST_STATIC_CONSTANT(bool, value = (mpl::contains< T, U >::type::value)); | |
248 | }; | |
249 | }; | |
250 | ||
251 | //! Attribute value reference implementation for multiple types case | |
252 | template< typename T, typename TagT > | |
253 | class variant_ref | |
254 | { | |
255 | public: | |
256 | //! Referenced value type | |
257 | typedef T value_type; | |
258 | //! Tag type | |
259 | typedef TagT tag_type; | |
260 | ||
261 | protected: | |
262 | //! Traits for testing type compatibility with the reference wrapper | |
263 | typedef variant_ref_compatibility_traits compatibility_traits; | |
264 | ||
265 | protected: | |
266 | //! Pointer to the value | |
267 | const void* m_ptr; | |
268 | //! Type index | |
269 | unsigned int m_type_idx; | |
270 | ||
271 | protected: | |
272 | //! Default constructor | |
273 | variant_ref() BOOST_NOEXCEPT : m_ptr(NULL), m_type_idx(0) | |
274 | { | |
275 | } | |
276 | ||
277 | //! Initializing constructor | |
278 | template< typename U > | |
279 | explicit variant_ref(const U* p) BOOST_NOEXCEPT : m_ptr(p), m_type_idx(mpl::index_of< value_type, U >::type::value) | |
280 | { | |
281 | } | |
282 | ||
283 | public: | |
284 | //! Resets the reference | |
285 | void reset() BOOST_NOEXCEPT | |
286 | { | |
287 | m_ptr = NULL; | |
288 | m_type_idx = 0; | |
289 | } | |
290 | ||
291 | //! Returns a pointer to the referred value | |
292 | template< typename U > | |
293 | typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, const U* >::type get_ptr() const BOOST_NOEXCEPT | |
294 | { | |
295 | if (m_type_idx == static_cast< unsigned int >(mpl::index_of< value_type, U >::type::value)) | |
296 | return static_cast< const U* >(m_ptr); | |
297 | else | |
298 | return NULL; | |
299 | } | |
300 | ||
301 | //! Returns a reference to the value | |
302 | template< typename U > | |
303 | typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, U const& >::type get() const BOOST_NOEXCEPT | |
304 | { | |
305 | const U* const p = get_ptr< U >(); | |
306 | BOOST_ASSERT(p != NULL); | |
307 | return *p; | |
308 | } | |
309 | ||
310 | //! Returns the stored type index | |
311 | unsigned int which() const BOOST_NOEXCEPT | |
312 | { | |
313 | return m_type_idx; | |
314 | } | |
315 | ||
316 | //! Swaps two reference wrappers | |
317 | void swap(variant_ref& that) BOOST_NOEXCEPT | |
318 | { | |
319 | const void* p = m_ptr; | |
320 | m_ptr = that.m_ptr; | |
321 | that.m_ptr = p; | |
322 | unsigned int type_idx = m_type_idx; | |
323 | m_type_idx = that.m_type_idx; | |
324 | that.m_type_idx = type_idx; | |
325 | } | |
326 | ||
327 | //! Applies a visitor function object to the referred value | |
328 | template< typename VisitorT > | |
329 | typename VisitorT::result_type apply_visitor(VisitorT visitor) const | |
330 | { | |
331 | BOOST_ASSERT(m_ptr != NULL); | |
332 | return do_apply_visitor(visitor); | |
333 | } | |
334 | ||
335 | //! Applies a visitor function object to the referred value | |
336 | template< typename VisitorT > | |
337 | typename boost::enable_if_c< is_void< typename VisitorT::result_type >::value, bool >::type apply_visitor_optional(VisitorT visitor) const | |
338 | { | |
339 | if (m_ptr) | |
340 | { | |
341 | do_apply_visitor(visitor); | |
342 | return true; | |
343 | } | |
344 | else | |
345 | return false; | |
346 | } | |
347 | ||
348 | //! Applies a visitor function object to the referred value | |
349 | template< typename VisitorT > | |
350 | typename boost::disable_if_c< is_void< typename VisitorT::result_type >::value, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const | |
351 | { | |
352 | typedef optional< typename VisitorT::result_type > result_type; | |
353 | if (m_ptr) | |
354 | return result_type(do_apply_visitor(visitor)); | |
355 | else | |
356 | return result_type(); | |
357 | } | |
358 | ||
359 | //! Applies a visitor function object to the referred value or returns a default value | |
360 | template< typename VisitorT, typename DefaultT > | |
361 | typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const | |
362 | { | |
363 | if (m_ptr) | |
364 | return do_apply_visitor(visitor); | |
365 | else | |
366 | return def_val; | |
367 | } | |
368 | ||
369 | //! Applies a visitor function object to the referred value or returns a default value | |
370 | template< typename VisitorT, typename DefaultT > | |
371 | typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const | |
372 | { | |
373 | if (m_ptr) | |
374 | return do_apply_visitor(visitor); | |
375 | else | |
376 | return def_val; | |
377 | } | |
378 | ||
379 | private: | |
380 | template< typename VisitorT > | |
381 | typename VisitorT::result_type do_apply_visitor(VisitorT& visitor) const | |
382 | { | |
383 | BOOST_ASSERT(m_type_idx < static_cast< unsigned int >(mpl::size< value_type >::value)); | |
384 | return apply_visitor_dispatch< value_type, VisitorT >::call(m_ptr, m_type_idx, visitor); | |
385 | } | |
386 | }; | |
387 | ||
388 | template< typename T, typename TagT > | |
389 | struct value_ref_base | |
390 | { | |
391 | typedef typename mpl::eval_if< | |
392 | mpl::and_< mpl::is_sequence< T >, mpl::equal_to< mpl::size< T >, mpl::int_< 1 > > >, | |
393 | mpl::front< T >, | |
394 | mpl::identity< T > | |
395 | >::type value_type; | |
396 | ||
397 | typedef typename mpl::if_< | |
398 | mpl::is_sequence< value_type >, | |
399 | variant_ref< value_type, TagT >, | |
400 | singular_ref< value_type, TagT > | |
401 | >::type type; | |
402 | }; | |
403 | ||
404 | } // namespace aux | |
405 | ||
406 | /*! | |
407 | * \brief Reference wrapper for a stored attribute value. | |
408 | * | |
409 | * The \c value_ref class template provides access to the stored attribute value. It is not a traditional reference wrapper | |
410 | * 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 | |
411 | * interface and behavior combines features of Boost.Ref, Boost.Optional and Boost.Variant, depending on the use case. | |
412 | * | |
413 | * The template parameter \c T can be a single type or an MPL sequence of possible types being referred. The reference wrapper | |
414 | * will act as either an optional reference or an optional variant of references to the specified types. In any case, the | |
415 | * referred values will not be modifiable (i.e. \c value_ref always models a const reference). | |
416 | * | |
417 | * Template parameter \c TagT is optional. It can be used for customizing the operations on this reference wrapper, such as | |
418 | * putting the referred value to log. | |
419 | */ | |
420 | template< typename T, typename TagT > | |
421 | class value_ref : | |
422 | public aux::value_ref_base< T, TagT >::type | |
423 | { | |
424 | #ifndef BOOST_LOG_DOXYGEN_PASS | |
425 | public: | |
426 | typedef void _has_basic_formatting_ostream_insert_operator; | |
427 | #endif | |
428 | ||
429 | private: | |
430 | //! Base implementation type | |
431 | typedef typename aux::value_ref_base< T, TagT >::type base_type; | |
432 | //! Traits for testing type compatibility with the reference wrapper | |
433 | typedef typename base_type::compatibility_traits compatibility_traits; | |
434 | ||
435 | public: | |
436 | #ifndef BOOST_LOG_DOXYGEN_PASS | |
437 | //! Referenced value type | |
438 | typedef typename base_type::value_type value_type; | |
439 | #else | |
440 | //! Referenced value type | |
441 | typedef T value_type; | |
442 | //! Tag type | |
443 | typedef TagT tag_type; | |
444 | #endif | |
445 | ||
446 | public: | |
447 | /*! | |
448 | * Default constructor. Creates a reference wrapper that does not refer to a value. | |
449 | */ | |
450 | BOOST_DEFAULTED_FUNCTION(value_ref(), BOOST_NOEXCEPT {}) | |
451 | ||
452 | /*! | |
453 | * Copy constructor. | |
454 | */ | |
455 | BOOST_DEFAULTED_FUNCTION(value_ref(value_ref const& that), BOOST_NOEXCEPT : base_type(static_cast< base_type const& >(that)) {}) | |
456 | ||
457 | /*! | |
458 | * Initializing constructor. Creates a reference wrapper that refers to the specified value. | |
459 | */ | |
460 | template< typename U > | |
461 | explicit value_ref(U const& val | |
462 | #ifndef BOOST_LOG_DOXYGEN_PASS | |
463 | // MSVC-8 can't handle SFINAE in this case properly and often wrongly disables this constructor | |
464 | #if !defined(_MSC_VER) || (_MSC_VER + 0) >= 1500 | |
465 | , 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() | |
466 | #endif | |
467 | #endif | |
468 | ) BOOST_NOEXCEPT : | |
469 | base_type(boost::addressof(val)) | |
470 | { | |
471 | } | |
472 | ||
473 | /*! | |
474 | * The operator verifies if the wrapper refers to a value. | |
475 | */ | |
476 | BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() | |
477 | ||
478 | /*! | |
479 | * The operator verifies if the wrapper does not refer to a value. | |
480 | */ | |
481 | bool operator! () const BOOST_NOEXCEPT | |
482 | { | |
483 | return !this->m_ptr; | |
484 | } | |
485 | ||
486 | /*! | |
487 | * \return \c true if the wrapper does not refer to a value. | |
488 | */ | |
489 | bool empty() const BOOST_NOEXCEPT | |
490 | { | |
491 | return !this->m_ptr; | |
492 | } | |
493 | ||
494 | /*! | |
495 | * Swaps two reference wrappers | |
496 | */ | |
497 | void swap(value_ref& that) BOOST_NOEXCEPT | |
498 | { | |
499 | base_type::swap(that); | |
500 | } | |
501 | }; | |
502 | ||
503 | //! Free swap function | |
504 | template< typename T, typename TagT > | |
505 | inline void swap(value_ref< T, TagT >& left, value_ref< T, TagT >& right) | |
506 | { | |
507 | left.swap(right); | |
508 | } | |
509 | ||
510 | //! Stream output operator | |
511 | template< typename CharT, typename TraitsT, typename T, typename TagT > | |
512 | inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, value_ref< T, TagT > const& val) | |
513 | { | |
514 | if (!!val) | |
515 | val.apply_visitor(boost::log::bind_output(strm)); | |
516 | return strm; | |
517 | } | |
518 | ||
519 | //! Log formatting operator | |
520 | template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename TagT > | |
521 | inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, value_ref< T, TagT > const& val) | |
522 | { | |
523 | if (!!val) | |
524 | val.apply_visitor(boost::log::bind_to_log< TagT >(strm)); | |
525 | return strm; | |
526 | } | |
527 | ||
528 | // Equality comparison | |
529 | template< typename T, typename TagT, typename U > | |
530 | inline bool operator== (value_ref< T, TagT > const& left, U const& right) | |
531 | { | |
532 | return left.apply_visitor_or_default(binder2nd< equal_to, U const& >(equal_to(), right), false); | |
533 | } | |
534 | ||
535 | template< typename U, typename T, typename TagT > | |
536 | inline bool operator== (U const& left, value_ref< T, TagT > const& right) | |
537 | { | |
538 | return right.apply_visitor_or_default(binder1st< equal_to, U const& >(equal_to(), left), false); | |
539 | } | |
540 | ||
541 | template< typename T1, typename TagT1, typename T2, typename TagT2 > | |
542 | inline bool operator== (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) | |
543 | { | |
544 | if (!left && !right) | |
545 | return true; | |
546 | return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, equal_to >(right, false), false); | |
547 | } | |
548 | ||
549 | // Inequality comparison | |
550 | template< typename T, typename TagT, typename U > | |
551 | inline bool operator!= (value_ref< T, TagT > const& left, U const& right) | |
552 | { | |
553 | return left.apply_visitor_or_default(binder2nd< not_equal_to, U const& >(not_equal_to(), right), false); | |
554 | } | |
555 | ||
556 | template< typename U, typename T, typename TagT > | |
557 | inline bool operator!= (U const& left, value_ref< T, TagT > const& right) | |
558 | { | |
559 | return right.apply_visitor_or_default(binder1st< not_equal_to, U const& >(not_equal_to(), left), false); | |
560 | } | |
561 | ||
562 | template< typename T1, typename TagT1, typename T2, typename TagT2 > | |
563 | inline bool operator!= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) | |
564 | { | |
565 | if (!left && !right) | |
566 | return false; | |
567 | return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, not_equal_to >(right, false), false); | |
568 | } | |
569 | ||
570 | // Less than ordering | |
571 | template< typename T, typename TagT, typename U > | |
572 | inline bool operator< (value_ref< T, TagT > const& left, U const& right) | |
573 | { | |
574 | return left.apply_visitor_or_default(binder2nd< less, U const& >(less(), right), false); | |
575 | } | |
576 | ||
577 | template< typename U, typename T, typename TagT > | |
578 | inline bool operator< (U const& left, value_ref< T, TagT > const& right) | |
579 | { | |
580 | return right.apply_visitor_or_default(binder1st< less, U const& >(less(), left), false); | |
581 | } | |
582 | ||
583 | template< typename T1, typename TagT1, typename T2, typename TagT2 > | |
584 | inline bool operator< (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) | |
585 | { | |
586 | return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less >(right, false), false); | |
587 | } | |
588 | ||
589 | // Greater than ordering | |
590 | template< typename T, typename TagT, typename U > | |
591 | inline bool operator> (value_ref< T, TagT > const& left, U const& right) | |
592 | { | |
593 | return left.apply_visitor_or_default(binder2nd< greater, U const& >(greater(), right), false); | |
594 | } | |
595 | ||
596 | template< typename U, typename T, typename TagT > | |
597 | inline bool operator> (U const& left, value_ref< T, TagT > const& right) | |
598 | { | |
599 | return right.apply_visitor_or_default(binder1st< greater, U const& >(greater(), left), false); | |
600 | } | |
601 | ||
602 | template< typename T1, typename TagT1, typename T2, typename TagT2 > | |
603 | inline bool operator> (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) | |
604 | { | |
605 | return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater >(right, false), false); | |
606 | } | |
607 | ||
608 | // Less or equal ordering | |
609 | template< typename T, typename TagT, typename U > | |
610 | inline bool operator<= (value_ref< T, TagT > const& left, U const& right) | |
611 | { | |
612 | return left.apply_visitor_or_default(binder2nd< less_equal, U const& >(less_equal(), right), false); | |
613 | } | |
614 | ||
615 | template< typename U, typename T, typename TagT > | |
616 | inline bool operator<= (U const& left, value_ref< T, TagT > const& right) | |
617 | { | |
618 | return right.apply_visitor_or_default(binder1st< less_equal, U const& >(less_equal(), left), false); | |
619 | } | |
620 | ||
621 | template< typename T1, typename TagT1, typename T2, typename TagT2 > | |
622 | inline bool operator<= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) | |
623 | { | |
624 | if (!left && !right) | |
625 | return true; | |
626 | return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less_equal >(right, false), false); | |
627 | } | |
628 | ||
629 | // Greater or equal ordering | |
630 | template< typename T, typename TagT, typename U > | |
631 | inline bool operator>= (value_ref< T, TagT > const& left, U const& right) | |
632 | { | |
633 | return left.apply_visitor_or_default(binder2nd< greater_equal, U const& >(greater_equal(), right), false); | |
634 | } | |
635 | ||
636 | template< typename U, typename T, typename TagT > | |
637 | inline bool operator>= (U const& left, value_ref< T, TagT > const& right) | |
638 | { | |
639 | return right.apply_visitor_or_default(binder1st< greater_equal, U const& >(greater_equal(), left), false); | |
640 | } | |
641 | ||
642 | template< typename T1, typename TagT1, typename T2, typename TagT2 > | |
643 | inline bool operator>= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right) | |
644 | { | |
645 | if (!left && !right) | |
646 | return true; | |
647 | return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater_equal >(right, false), false); | |
648 | } | |
649 | ||
650 | BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
651 | ||
652 | } // namespace boost | |
653 | ||
654 | #include <boost/log/detail/footer.hpp> | |
655 | ||
656 | #endif // BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_ |