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