]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/log/include/boost/log/attributes/attribute_set.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / log / include / boost / log / attributes / attribute_set.hpp
CommitLineData
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 attribute_set.hpp
9 * \author Andrey Semashev
10 * \date 08.03.2007
11 *
12 * This header contains definition of the attribute set container.
13 */
14
15#ifndef BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
16#define BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
17
18#include <cstddef>
19#include <utility>
20#include <iterator>
21#include <boost/mpl/if.hpp>
22#include <boost/move/core.hpp>
23#include <boost/log/detail/config.hpp>
24#include <boost/log/attributes/attribute_name.hpp>
25#include <boost/log/attributes/attribute.hpp>
26#include <boost/log/detail/header.hpp>
27
28#ifdef BOOST_HAS_PRAGMA_ONCE
29#pragma once
30#endif
31
32namespace boost {
33
34BOOST_LOG_OPEN_NAMESPACE
35
36class attribute_set;
37class attribute_value_set;
38
39namespace aux {
40
41//! Reference proxy object to implement \c operator[]
42class attribute_set_reference_proxy
43{
44private:
45 //! Key type
46 typedef attribute_name key_type;
47 //! Mapped attribute type
48 typedef attribute mapped_type;
49
50private:
51 attribute_set* const m_pContainer;
52 const key_type m_key;
53
54public:
55 //! Constructor
56 explicit attribute_set_reference_proxy(attribute_set* pContainer, key_type const& key) BOOST_NOEXCEPT :
57 m_pContainer(pContainer),
58 m_key(key)
59 {
60 }
61
62 //! Conversion operator (would be invoked in case of reading from the container)
63 BOOST_FORCEINLINE operator mapped_type() const BOOST_NOEXCEPT
64 {
65 return read_mapped_value();
66 }
67 //! Assignment operator (would be invoked in case of writing to the container)
68 mapped_type& operator= (mapped_type const& val) const;
69
70private:
71 //! Reads the referenced mapped value from the container
72 mapped_type read_mapped_value() const BOOST_NOEXCEPT;
73};
74
75} // namespace aux
76
77/*!
78 * \brief An attribute set class.
79 *
80 * An attribute set is an associative container with attribute name as a key and
81 * pointer to the attribute as a mapped value. The container allows storing only one element for each distinct
82 * key value. In most regards attribute set container provides interface similar to \c std::unordered_map.
83 * However, there are differences in \c operator[] semantics and a number of optimizations with regard to iteration.
84 * Besides, attribute names are stored as a read-only <tt>attribute_name</tt>'s instead of \c std::string,
85 * which saves memory and CPU time.
86 */
87class attribute_set
88{
89 BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_set)
90
91 friend class attribute_value_set;
92 friend class aux::attribute_set_reference_proxy;
93
94public:
95 //! Key type
96 typedef attribute_name key_type;
97 //! Mapped attribute type
98 typedef attribute mapped_type;
99
100 //! Value type
101 typedef std::pair< const key_type, mapped_type > value_type;
102 //! Reference type
103 typedef value_type& reference;
104 //! Const reference type
105 typedef value_type const& const_reference;
106 //! Pointer type
107 typedef value_type* pointer;
108 //! Const pointer type
109 typedef value_type const* const_pointer;
110 //! Size type
111 typedef std::size_t size_type;
112 //! Difference type
113 typedef std::ptrdiff_t difference_type;
114
115private:
116 //! \cond
117
118 //! Implementation
119 struct implementation;
120 friend struct implementation;
121
122 //! A base class for the container nodes
123 struct node_base
124 {
125 node_base* m_pPrev;
126 node_base* m_pNext;
127
128 node_base();
129
130 BOOST_DELETED_FUNCTION(node_base(node_base const&))
131 BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&))
132 };
133
134 //! Container elements
135 struct node;
136 friend struct node;
137 struct node :
138 public node_base
139 {
140 value_type m_Value;
141
142 node(key_type const& key, mapped_type const& data);
143 };
144
145 //! Iterator class
146#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
147 template< bool fConstV > class iter;
148 template< bool fConstV > friend class iter;
149#endif
150 template< bool fConstV >
151 class iter
152 {
153 friend class iter< !fConstV >;
154 friend class attribute_set;
155
156 public:
157 // Standard typedefs
158 typedef attribute_set::difference_type difference_type;
159 typedef attribute_set::value_type value_type;
160 typedef typename mpl::if_c<
161 fConstV,
162 attribute_set::const_reference,
163 attribute_set::reference
164 >::type reference;
165 typedef typename mpl::if_c<
166 fConstV,
167 attribute_set::const_pointer,
168 attribute_set::pointer
169 >::type pointer;
170 typedef std::bidirectional_iterator_tag iterator_category;
171
172 public:
173 // Constructors
174 BOOST_CONSTEXPR iter() : m_pNode(NULL) {}
175 explicit iter(node_base* pNode) BOOST_NOEXCEPT : m_pNode(pNode) {}
176 iter(iter< false > const& that) BOOST_NOEXCEPT : m_pNode(that.m_pNode) {}
177
178 //! Assignment
179 template< bool f >
180 iter& operator= (iter< f > const& that) BOOST_NOEXCEPT
181 {
182 m_pNode = that.m_pNode;
183 return *this;
184 }
185
186 // Comparison
187 template< bool f >
188 bool operator== (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode == that.m_pNode); }
189 template< bool f >
190 bool operator!= (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode != that.m_pNode); }
191
192 // Modification
193 iter& operator++ () BOOST_NOEXCEPT
194 {
195 m_pNode = m_pNode->m_pNext;
196 return *this;
197 }
198 iter& operator-- () BOOST_NOEXCEPT
199 {
200 m_pNode = m_pNode->m_pPrev;
201 return *this;
202 }
203 iter operator++ (int) BOOST_NOEXCEPT
204 {
205 iter tmp(*this);
206 m_pNode = m_pNode->m_pNext;
207 return tmp;
208 }
209 iter operator-- (int) BOOST_NOEXCEPT
210 {
211 iter tmp(*this);
212 m_pNode = m_pNode->m_pPrev;
213 return tmp;
214 }
215
216 // Dereferencing
217 pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); }
218 reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; }
219
220 node_base* base() const BOOST_NOEXCEPT { return m_pNode; }
221
222 private:
223 node_base* m_pNode;
224 };
225
226 //! \endcond
227
228public:
229#ifndef BOOST_LOG_DOXYGEN_PASS
230 //! Iterator type
231 typedef iter< false > iterator;
232 //! Const iterator type
233 typedef iter< true > const_iterator;
234#else
235 /*!
236 * Iterator type. The iterator complies to the bidirectional iterator requirements.
237 */
238 typedef implementation_defined iterator;
239 /*!
240 * Constant iterator type. The iterator complies to the bidirectional iterator requirements with read-only capabilities.
241 */
242 typedef implementation_defined const_iterator;
243#endif // BOOST_LOG_DOXYGEN_PASS
244
245private:
246 //! Pointer to implementation
247 implementation* m_pImpl;
248
249public:
250 /*!
251 * Default constructor.
252 *
253 * \post <tt>empty() == true</tt>
254 */
255 BOOST_LOG_API attribute_set();
256
257 /*!
258 * Copy constructor.
259 *
260 * \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt>
261 */
262 BOOST_LOG_API attribute_set(attribute_set const& that);
263
264 /*!
265 * Move constructor
266 */
267 attribute_set(BOOST_RV_REF(attribute_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl)
268 {
269 that.m_pImpl = NULL;
270 }
271
272 /*!
273 * Destructor. All stored references to attributes are released.
274 */
275 BOOST_LOG_API ~attribute_set() BOOST_NOEXCEPT;
276
277 /*!
278 * Copy assignment operator.
279 *
280 * \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt>
281 */
282 attribute_set& operator= (attribute_set that) BOOST_NOEXCEPT
283 {
284 this->swap(that);
285 return *this;
286 }
287
288 /*!
289 * Swaps two instances of the container.
290 *
291 * \b Throws: Nothing.
292 */
293 void swap(attribute_set& that) BOOST_NOEXCEPT
294 {
295 implementation* const p = m_pImpl;
296 m_pImpl = that.m_pImpl;
297 that.m_pImpl = p;
298 }
299
300 /*!
301 * \return Iterator to the first element of the container.
302 */
303 BOOST_LOG_API iterator begin() BOOST_NOEXCEPT;
304 /*!
305 * \return Iterator to the after-the-last element of the container.
306 */
307 BOOST_LOG_API iterator end() BOOST_NOEXCEPT;
308 /*!
309 * \return Constant iterator to the first element of the container.
310 */
311 BOOST_LOG_API const_iterator begin() const BOOST_NOEXCEPT;
312 /*!
313 * \return Constant iterator to the after-the-last element of the container.
314 */
315 BOOST_LOG_API const_iterator end() const BOOST_NOEXCEPT;
316
317 /*!
318 * \return Number of elements in the container.
319 */
320 BOOST_LOG_API size_type size() const BOOST_NOEXCEPT;
321 /*!
322 * \return true if there are no elements in the container, false otherwise.
323 */
324 bool empty() const BOOST_NOEXCEPT { return (this->size() == 0); }
325
326 /*!
327 * The method finds the attribute by name.
328 *
329 * \param key Attribute name.
330 * \return Iterator to the found element or end() if the attribute with such name is not found.
331 */
332 BOOST_LOG_API iterator find(key_type key) BOOST_NOEXCEPT;
333 /*!
334 * The method finds the attribute by name.
335 *
336 * \param key Attribute name.
337 * \return Iterator to the found element or \c end() if the attribute with such name is not found.
338 */
339 const_iterator find(key_type key) const BOOST_NOEXCEPT
340 {
341 return const_iterator(const_cast< attribute_set* >(this)->find(key));
342 }
343 /*!
344 * The method counts the number of the attribute occurrences in the container. Since there can be only one
345 * attribute with a particular key, the method always return 0 or 1.
346 *
347 * \param key Attribute name.
348 * \return The number of times the attribute is found in the container.
349 */
350 size_type count(key_type key) const BOOST_NOEXCEPT { return size_type(this->find(key) != this->end()); }
351
352 /*!
353 * Combined lookup/insertion operator. The operator semantics depends on the further usage of the returned reference.
354 * \li If the reference is used as an assignment target, the assignment expression is equivalent to element insertion,
355 * where the element is composed of the second argument of the \c operator[] as a key and the second argument of assignment
356 * as a mapped value.
357 * \li If the returned reference is used in context where a conversion to the mapped type is required,
358 * the result of the conversion is equivalent to the mapped value found with the second argument of the \c operator[] as a key,
359 * if such an element exists in the container, or a default-constructed mapped value, if an element does not exist in the
360 * container.
361 *
362 * \param key Attribute name.
363 * \return A smart reference object of unspecified type.
364 */
365 aux::attribute_set_reference_proxy operator[] (key_type key) BOOST_NOEXCEPT
366 {
367 return aux::attribute_set_reference_proxy(this, key);
368 }
369 /*!
370 * Lookup operator
371 *
372 * \param key Attribute name.
373 * \return If an element with the corresponding attribute name is found in the container, its mapped value
374 * is returned. Otherwise a default-constructed mapped value is returned.
375 */
376 mapped_type operator[] (key_type key) const BOOST_NOEXCEPT
377 {
378 const_iterator it = this->find(key);
379 if (it != end())
380 return it->second;
381 else
382 return mapped_type();
383 }
384
385 /*!
386 * Insertion method
387 *
388 * \param key Attribute name.
389 * \param data Pointer to the attribute. Must not be NULL.
390 * \returns A pair of values. If second is true, the insertion succeeded and the first component points to the
391 * inserted element. Otherwise the first component points to the element that prevents insertion.
392 */
393 BOOST_LOG_API std::pair< iterator, bool > insert(key_type key, mapped_type const& data);
394
395 /*!
396 * Insertion method
397 *
398 * \param value An element to be inserted.
399 * \returns A pair of values. If second is true, the insertion succeeded and the first component points to the
400 * inserted element. Otherwise the first component points to the element that prevents insertion.
401 */
402 std::pair< iterator, bool > insert(const_reference value)
403 {
404 return this->insert(value.first, value.second);
405 }
406
407 /*!
408 * Mass insertion method.
409 *
410 * \param begin A forward iterator that points to the first element to be inserted.
411 * \param end A forward iterator that points to the after-the-last element to be inserted.
412 */
413 template< typename FwdIteratorT >
414 void insert(FwdIteratorT begin, FwdIteratorT end)
415 {
416 for (; begin != end; ++begin)
417 this->insert(*begin);
418 }
419
420 /*!
421 * Mass insertion method with ability to acquire iterators to the inserted elements.
422 *
423 * \param begin A forward iterator that points to the first element to be inserted.
424 * \param end A forward iterator that points to the after-the-last element to be inserted.
425 * \param out An output iterator that receives results of insertion of the elements
426 */
427 template< typename FwdIteratorT, typename OutputIteratorT >
428 void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out)
429 {
430 for (; begin != end; ++begin, ++out)
431 *out = this->insert(*begin);
432 }
433
434 /*!
435 * The method erases all attributes with the specified name
436 *
437 * \post All iterators to the erased elements become invalid.
438 * \param key Attribute name.
439 * \return Tne number of erased elements
440 */
441 BOOST_LOG_API size_type erase(key_type key) BOOST_NOEXCEPT;
442 /*!
443 * The method erases the specified attribute
444 *
445 * \post All iterators to the erased element become invalid.
446 * \param it A valid iterator to the element to be erased.
447 * \return Tne number of erased elements
448 */
449 BOOST_LOG_API void erase(iterator it) BOOST_NOEXCEPT;
450 /*!
451 * The method erases all attributes within the specified range
452 *
453 * \pre \a end is reachable from \a begin with a finite number of increments.
454 * \post All iterators to the erased elements become invalid.
455 * \param begin An iterator that points to the first element to be erased.
456 * \param end An iterator that points to the after-the-last element to be erased.
457 */
458 BOOST_LOG_API void erase(iterator begin, iterator end) BOOST_NOEXCEPT;
459
460 /*!
461 * The method removes all elements from the container
462 *
463 * \post <tt>empty() == true</tt>
464 */
465 BOOST_LOG_API void clear() BOOST_NOEXCEPT;
466};
467
468/*!
469 * Free swap overload
470 */
471inline void swap(attribute_set& left, attribute_set& right) BOOST_NOEXCEPT
472{
473 left.swap(right);
474}
475
476namespace aux {
477
478//! Reads the referenced mapped value from the container
479inline attribute_set_reference_proxy::mapped_type attribute_set_reference_proxy::read_mapped_value() const BOOST_NOEXCEPT
480{
481 attribute_set::iterator it = m_pContainer->find(m_key);
482 if (it != m_pContainer->end())
483 return it->second;
484 else
485 return mapped_type();
486}
487
488//! Assignment operator (would be invoked in case of writing to the container)
489inline attribute_set_reference_proxy::mapped_type& attribute_set_reference_proxy::operator= (mapped_type const& val) const
490{
491 std::pair< attribute_set::iterator, bool > res = m_pContainer->insert(m_key, val);
492 if (!res.second)
493 res.first->second = val;
494 return res.first->second;
495}
496
497} // namespace aux
498
499#ifndef BOOST_LOG_DOXYGEN_PASS
500inline attribute& attribute::operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT
501{
502 attribute attr = that;
503 this->swap(attr);
504 return *this;
505}
506#endif
507
508BOOST_LOG_CLOSE_NAMESPACE // namespace log
509
510} // namespace boost
511
512#include <boost/log/detail/footer.hpp>
513
514#endif // BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_