annotate DEPENDENCIES/generic/include/boost/log/attributes/attribute_value_set.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
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 attribute_value_set.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 21.04.2007
Chris@16 11 *
Chris@16 12 * This header file contains definition of attribute value set. The set is constructed from
Chris@16 13 * three attribute sets (global, thread-specific and source-specific) and contains attribute
Chris@16 14 * values.
Chris@16 15 */
Chris@16 16
Chris@16 17 #ifndef BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
Chris@16 18 #define BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
Chris@16 19
Chris@16 20 #include <cstddef>
Chris@16 21 #include <utility>
Chris@16 22 #include <iterator>
Chris@16 23 #include <boost/move/core.hpp>
Chris@16 24 #include <boost/log/detail/config.hpp>
Chris@16 25 #include <boost/log/attributes/attribute_name.hpp>
Chris@16 26 #include <boost/log/attributes/attribute.hpp>
Chris@16 27 #include <boost/log/attributes/attribute_value.hpp>
Chris@16 28 #include <boost/log/attributes/attribute_set.hpp>
Chris@16 29 #include <boost/log/expressions/keyword_fwd.hpp>
Chris@16 30 #include <boost/log/detail/header.hpp>
Chris@16 31
Chris@16 32 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 33 #pragma once
Chris@16 34 #endif
Chris@16 35
Chris@16 36 namespace boost {
Chris@16 37
Chris@16 38 BOOST_LOG_OPEN_NAMESPACE
Chris@16 39
Chris@16 40 /*!
Chris@16 41 * \brief A set of attribute values
Chris@16 42 *
Chris@16 43 * The set of attribute values is an associative container with attribute name as a key and
Chris@16 44 * a pointer to attribute value object as a mapped type. This is a collection of elements with unique
Chris@16 45 * keys, that is, there can be only one attribute value with a given name in the set. With respect to
Chris@16 46 * read-only capabilities, the set interface is close to \c std::unordered_map.
Chris@16 47 *
Chris@16 48 * The set is designed to be only capable of adding elements to it. Once added, the attribute value
Chris@16 49 * cannot be removed from the set.
Chris@16 50 *
Chris@16 51 * An instance of attribute value set can be constructed from three attribute sets. The constructor attempts to
Chris@16 52 * accommodate values of all attributes from the sets. The situation when a same-named attribute is found
Chris@16 53 * in more than one attribute set is possible. This problem is solved on construction of the value set: the three
Chris@16 54 * attribute sets have different priorities when it comes to solving conflicts.
Chris@16 55 *
Chris@16 56 * From the library perspective the three source attribute sets are global, thread-specific and source-specific
Chris@16 57 * attributes, with the latter having the highest priority. This feature allows to override attributes of wider scopes
Chris@16 58 * with the more specific ones.
Chris@16 59 *
Chris@16 60 * For sake of performance, the attribute values are not immediately acquired from attribute sets at construction.
Chris@16 61 * Instead, on-demand acquisition is performed either on iterator dereferencing or on call to the \c freeze method.
Chris@16 62 * Once acquired, the attribute value stays within the set until its destruction. This nuance does not affect
Chris@16 63 * other set properties, such as size or lookup ability. The logging core automatically freezes the set
Chris@16 64 * at the right point, so users should not be bothered unless they manually create attribute value sets.
Chris@16 65 *
Chris@16 66 * \note The attribute sets that were used for the value set construction must not be modified or destroyed
Chris@16 67 * until the value set is frozen. Otherwise the behavior is undefined.
Chris@16 68 */
Chris@16 69 class attribute_value_set
Chris@16 70 {
Chris@16 71 BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_value_set)
Chris@16 72
Chris@16 73 public:
Chris@16 74 //! Key type
Chris@16 75 typedef attribute_name key_type;
Chris@16 76 //! Mapped attribute type
Chris@16 77 typedef attribute_value mapped_type;
Chris@16 78
Chris@16 79 //! Value type
Chris@16 80 typedef std::pair< const key_type, mapped_type > value_type;
Chris@16 81 //! Reference type
Chris@16 82 typedef value_type& reference;
Chris@16 83 //! Const reference type
Chris@16 84 typedef value_type const& const_reference;
Chris@16 85 //! Pointer type
Chris@16 86 typedef value_type* pointer;
Chris@16 87 //! Const pointer type
Chris@16 88 typedef value_type const* const_pointer;
Chris@16 89 //! Size type
Chris@16 90 typedef std::size_t size_type;
Chris@16 91 //! Pointer difference type
Chris@16 92 typedef std::ptrdiff_t difference_type;
Chris@16 93
Chris@16 94 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 95
Chris@16 96 private:
Chris@16 97 struct implementation;
Chris@16 98 friend struct implementation;
Chris@16 99
Chris@16 100 //! A base class for the container nodes
Chris@16 101 struct node_base
Chris@16 102 {
Chris@16 103 node_base* m_pPrev;
Chris@16 104 node_base* m_pNext;
Chris@16 105
Chris@16 106 node_base();
Chris@16 107
Chris@16 108 BOOST_DELETED_FUNCTION(node_base(node_base const&))
Chris@16 109 BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&))
Chris@16 110 };
Chris@16 111
Chris@16 112 //! Container elements
Chris@16 113 struct node;
Chris@16 114 friend struct node;
Chris@16 115 struct node :
Chris@16 116 public node_base
Chris@16 117 {
Chris@16 118 value_type m_Value;
Chris@16 119 bool m_DynamicallyAllocated;
Chris@16 120
Chris@16 121 node(key_type const& key, mapped_type& data, bool dynamic);
Chris@16 122 };
Chris@16 123
Chris@16 124 public:
Chris@16 125 class const_iterator;
Chris@16 126 friend class const_iterator;
Chris@16 127 class const_iterator
Chris@16 128 {
Chris@16 129 public:
Chris@16 130 // Standard typedefs
Chris@16 131 typedef attribute_value_set::difference_type difference_type;
Chris@16 132 typedef attribute_value_set::value_type value_type;
Chris@16 133 typedef attribute_value_set::const_reference reference;
Chris@16 134 typedef attribute_value_set::const_pointer pointer;
Chris@16 135 typedef std::bidirectional_iterator_tag iterator_category;
Chris@16 136
Chris@16 137 public:
Chris@16 138 // Constructors
Chris@16 139 BOOST_CONSTEXPR const_iterator() : m_pNode(NULL), m_pContainer(NULL) {}
Chris@16 140 explicit const_iterator(node_base* n, attribute_value_set* cont) BOOST_NOEXCEPT :
Chris@16 141 m_pNode(n),
Chris@16 142 m_pContainer(cont)
Chris@16 143 {
Chris@16 144 }
Chris@16 145
Chris@16 146 // Comparison
Chris@16 147 bool operator== (const_iterator const& that) const BOOST_NOEXCEPT
Chris@16 148 {
Chris@16 149 return (m_pNode == that.m_pNode);
Chris@16 150 }
Chris@16 151 bool operator!= (const_iterator const& that) const BOOST_NOEXCEPT
Chris@16 152 {
Chris@16 153 return (m_pNode != that.m_pNode);
Chris@16 154 }
Chris@16 155
Chris@16 156 // Modification
Chris@16 157 const_iterator& operator++ ()
Chris@16 158 {
Chris@16 159 m_pContainer->freeze();
Chris@16 160 m_pNode = m_pNode->m_pNext;
Chris@16 161 return *this;
Chris@16 162 }
Chris@16 163 const_iterator& operator-- ()
Chris@16 164 {
Chris@16 165 m_pContainer->freeze();
Chris@16 166 m_pNode = m_pNode->m_pPrev;
Chris@16 167 return *this;
Chris@16 168 }
Chris@16 169 const_iterator operator++ (int)
Chris@16 170 {
Chris@16 171 const_iterator tmp(*this);
Chris@16 172 m_pContainer->freeze();
Chris@16 173 m_pNode = m_pNode->m_pNext;
Chris@16 174 return tmp;
Chris@16 175 }
Chris@16 176 const_iterator operator-- (int)
Chris@16 177 {
Chris@16 178 const_iterator tmp(*this);
Chris@16 179 m_pContainer->freeze();
Chris@16 180 m_pNode = m_pNode->m_pPrev;
Chris@16 181 return tmp;
Chris@16 182 }
Chris@16 183
Chris@16 184 // Dereferencing
Chris@16 185 pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); }
Chris@16 186 reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; }
Chris@16 187
Chris@16 188 private:
Chris@16 189 node_base* m_pNode;
Chris@16 190 attribute_value_set* m_pContainer;
Chris@16 191 };
Chris@16 192
Chris@16 193 #else
Chris@16 194
Chris@16 195 /*!
Chris@16 196 * Constant iterator type with bidirectional capabilities.
Chris@16 197 */
Chris@16 198 typedef implementation_defined const_iterator;
Chris@16 199
Chris@16 200 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 201
Chris@16 202 private:
Chris@16 203 //! Pointer to the container implementation
Chris@16 204 implementation* m_pImpl;
Chris@16 205
Chris@16 206 public:
Chris@16 207 /*!
Chris@16 208 * Default constructor
Chris@16 209 *
Chris@16 210 * The constructor creates an empty set which can be filled later by subsequent
Chris@16 211 * calls of \c insert method. Optionally, the amount of storage reserved for elements
Chris@16 212 * to be inserted may be passed to the constructor.
Chris@16 213 * The constructed set is frozen.
Chris@16 214 *
Chris@16 215 * \param reserve_count Number of elements to reserve space for.
Chris@16 216 */
Chris@16 217 BOOST_LOG_API explicit attribute_value_set(size_type reserve_count = 8);
Chris@16 218
Chris@16 219 /*!
Chris@16 220 * Move constructor
Chris@16 221 */
Chris@16 222 attribute_value_set(BOOST_RV_REF(attribute_value_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl)
Chris@16 223 {
Chris@16 224 that.m_pImpl = NULL;
Chris@16 225 }
Chris@16 226
Chris@16 227 /*!
Chris@16 228 * The constructor adopts three attribute sets into the value set.
Chris@16 229 * The \a source_attrs attributes have the greatest preference when a same-named
Chris@16 230 * attribute is found in several sets, \a global_attrs has the least.
Chris@16 231 * The constructed set is not frozen.
Chris@16 232 *
Chris@16 233 * \param source_attrs A set of source-specific attributes.
Chris@16 234 * \param thread_attrs A set of thread-specific attributes.
Chris@16 235 * \param global_attrs A set of global attributes.
Chris@16 236 * \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
Chris@16 237 */
Chris@16 238 BOOST_LOG_API attribute_value_set(
Chris@16 239 attribute_set const& source_attrs,
Chris@16 240 attribute_set const& thread_attrs,
Chris@16 241 attribute_set const& global_attrs,
Chris@16 242 size_type reserve_count = 8);
Chris@16 243
Chris@16 244 /*!
Chris@16 245 * The constructor adopts three attribute sets into the value set.
Chris@16 246 * The \a source_attrs attributes have the greatest preference when a same-named
Chris@16 247 * attribute is found in several sets, \a global_attrs has the least.
Chris@16 248 * The constructed set is not frozen.
Chris@16 249 *
Chris@16 250 * \pre The \a source_attrs set is frozen.
Chris@16 251 *
Chris@16 252 * \param source_attrs A set of source-specific attributes.
Chris@16 253 * \param thread_attrs A set of thread-specific attributes.
Chris@16 254 * \param global_attrs A set of global attributes.
Chris@16 255 * \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
Chris@16 256 */
Chris@16 257 BOOST_LOG_API attribute_value_set(
Chris@16 258 attribute_value_set const& source_attrs,
Chris@16 259 attribute_set const& thread_attrs,
Chris@16 260 attribute_set const& global_attrs,
Chris@16 261 size_type reserve_count = 8);
Chris@16 262
Chris@16 263 /*!
Chris@16 264 * The constructor adopts three attribute sets into the value set.
Chris@16 265 * The \a source_attrs attributes have the greatest preference when a same-named
Chris@16 266 * attribute is found in several sets, \a global_attrs has the least.
Chris@16 267 * The constructed set is not frozen.
Chris@16 268 *
Chris@16 269 * \pre The \a source_attrs set is frozen.
Chris@16 270 *
Chris@16 271 * \param source_attrs A set of source-specific attributes.
Chris@16 272 * \param thread_attrs A set of thread-specific attributes.
Chris@16 273 * \param global_attrs A set of global attributes.
Chris@16 274 * \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
Chris@16 275 */
Chris@16 276 attribute_value_set(
Chris@16 277 BOOST_RV_REF(attribute_value_set) source_attrs,
Chris@16 278 attribute_set const& thread_attrs,
Chris@16 279 attribute_set const& global_attrs,
Chris@16 280 size_type reserve_count = 8) : m_pImpl(NULL)
Chris@16 281 {
Chris@16 282 construct(static_cast< attribute_value_set& >(source_attrs), thread_attrs, global_attrs, reserve_count);
Chris@16 283 }
Chris@16 284
Chris@16 285 /*!
Chris@16 286 * Copy constructor.
Chris@16 287 *
Chris@16 288 * \pre The original set is frozen.
Chris@16 289 * \post The constructed set is frozen, <tt>std::equal(begin(), end(), that.begin()) == true</tt>
Chris@16 290 */
Chris@16 291 BOOST_LOG_API attribute_value_set(attribute_value_set const& that);
Chris@16 292
Chris@16 293 /*!
Chris@16 294 * Destructor. Releases all referenced attribute values.
Chris@16 295 */
Chris@16 296 BOOST_LOG_API ~attribute_value_set() BOOST_NOEXCEPT;
Chris@16 297
Chris@16 298 /*!
Chris@16 299 * Assignment operator
Chris@16 300 */
Chris@16 301 attribute_value_set& operator= (attribute_value_set that) BOOST_NOEXCEPT
Chris@16 302 {
Chris@16 303 this->swap(that);
Chris@16 304 return *this;
Chris@16 305 }
Chris@16 306
Chris@16 307 /*!
Chris@16 308 * Swaps two sets
Chris@16 309 *
Chris@16 310 * \b Throws: Nothing.
Chris@16 311 */
Chris@16 312 void swap(attribute_value_set& that) BOOST_NOEXCEPT
Chris@16 313 {
Chris@101 314 implementation* const p = m_pImpl;
Chris@16 315 m_pImpl = that.m_pImpl;
Chris@16 316 that.m_pImpl = p;
Chris@16 317 }
Chris@16 318
Chris@16 319 /*!
Chris@16 320 * \return Iterator to the first element of the set.
Chris@16 321 */
Chris@16 322 BOOST_LOG_API const_iterator begin() const;
Chris@16 323 /*!
Chris@16 324 * \return Iterator to the after-the-last element of the set.
Chris@16 325 */
Chris@16 326 BOOST_LOG_API const_iterator end() const;
Chris@16 327
Chris@16 328 /*!
Chris@16 329 * \return Number of elements in the set.
Chris@16 330 */
Chris@16 331 BOOST_LOG_API size_type size() const;
Chris@16 332 /*!
Chris@101 333 * \return \c true if there are no elements in the container, \c false otherwise.
Chris@16 334 */
Chris@16 335 bool empty() const { return (this->size() == 0); }
Chris@16 336
Chris@16 337 /*!
Chris@16 338 * The method finds the attribute value by name.
Chris@16 339 *
Chris@16 340 * \param key Attribute name.
Chris@16 341 * \return Iterator to the found element or \c end() if the attribute with such name is not found.
Chris@16 342 */
Chris@16 343 BOOST_LOG_API const_iterator find(key_type key) const;
Chris@16 344
Chris@16 345 /*!
Chris@16 346 * Alternative lookup syntax.
Chris@16 347 *
Chris@16 348 * \param key Attribute name.
Chris@16 349 * \return A pointer to the attribute value if it is found with \a key, default-constructed mapped value otherwise.
Chris@16 350 */
Chris@16 351 mapped_type operator[] (key_type key) const
Chris@16 352 {
Chris@16 353 const_iterator it = this->find(key);
Chris@16 354 if (it != this->end())
Chris@16 355 return it->second;
Chris@16 356 else
Chris@16 357 return mapped_type();
Chris@16 358 }
Chris@16 359
Chris@16 360 /*!
Chris@16 361 * Alternative lookup syntax.
Chris@16 362 *
Chris@16 363 * \param keyword Attribute keyword.
Chris@16 364 * \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
Chris@16 365 */
Chris@16 366 template< typename DescriptorT, template< typename > class ActorT >
Chris@16 367 typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
Chris@16 368 operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
Chris@16 369 {
Chris@16 370 typedef typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type attr_value_type;
Chris@16 371 typedef typename result_of::extract< attr_value_type, DescriptorT >::type result_type;
Chris@16 372 const_iterator it = this->find(keyword.get_name());
Chris@16 373 if (it != this->end())
Chris@16 374 return it->second.extract< attr_value_type, DescriptorT >();
Chris@16 375 else
Chris@16 376 return result_type();
Chris@16 377 }
Chris@16 378
Chris@16 379 /*!
Chris@16 380 * The method counts the number of the attribute value occurrences in the set. Since there can be only one
Chris@16 381 * attribute value with a particular key, the method always return 0 or 1.
Chris@16 382 *
Chris@16 383 * \param key Attribute name.
Chris@16 384 * \return The number of times the attribute value is found in the container.
Chris@16 385 */
Chris@16 386 size_type count(key_type key) const { return size_type(this->find(key) != this->end()); }
Chris@16 387
Chris@16 388 /*!
Chris@16 389 * The method acquires values of all adopted attributes.
Chris@16 390 *
Chris@16 391 * \post The set is frozen.
Chris@16 392 */
Chris@16 393 BOOST_LOG_API void freeze();
Chris@16 394
Chris@16 395 /*!
Chris@16 396 * Inserts an element into the set. The complexity of the operation is amortized constant.
Chris@16 397 *
Chris@16 398 * \pre The set is frozen.
Chris@16 399 *
Chris@16 400 * \param key The attribute name.
Chris@16 401 * \param mapped The attribute value.
Chris@16 402 *
Chris@16 403 * \returns An iterator to the inserted element and \c true if insertion succeeded. Otherwise,
Chris@16 404 * if the set already contains a same-named attribute value, iterator to the
Chris@16 405 * existing element and \c false.
Chris@16 406 */
Chris@16 407 BOOST_LOG_API std::pair< const_iterator, bool > insert(key_type key, mapped_type const& mapped);
Chris@16 408
Chris@16 409 /*!
Chris@16 410 * Inserts an element into the set. The complexity of the operation is amortized constant.
Chris@16 411 *
Chris@16 412 * \pre The set is frozen.
Chris@16 413 *
Chris@16 414 * \param value The attribute name and value.
Chris@16 415 *
Chris@16 416 * \returns An iterator to the inserted element and \c true if insertion succeeded. Otherwise,
Chris@16 417 * if the set already contains a same-named attribute value, iterator to the
Chris@16 418 * existing element and \c false.
Chris@16 419 */
Chris@16 420 std::pair< const_iterator, bool > insert(const_reference value) { return this->insert(value.first, value.second); }
Chris@16 421
Chris@16 422 /*!
Chris@16 423 * Mass insertion method. The complexity of the operation is linear to the number of elements inserted.
Chris@16 424 *
Chris@16 425 * \pre The set is frozen.
Chris@16 426 *
Chris@16 427 * \param begin A forward iterator that points to the first element to be inserted.
Chris@16 428 * \param end A forward iterator that points to the after-the-last element to be inserted.
Chris@16 429 */
Chris@16 430 template< typename FwdIteratorT >
Chris@16 431 void insert(FwdIteratorT begin, FwdIteratorT end)
Chris@16 432 {
Chris@16 433 for (; begin != end; ++begin)
Chris@16 434 this->insert(*begin);
Chris@16 435 }
Chris@16 436
Chris@16 437 /*!
Chris@16 438 * Mass insertion method with ability to acquire iterators to the inserted elements.
Chris@16 439 * The complexity of the operation is linear to the number of elements inserted times the complexity
Chris@16 440 * of filling the \a out iterator.
Chris@16 441 *
Chris@16 442 * \pre The set is frozen.
Chris@16 443 *
Chris@16 444 * \param begin A forward iterator that points to the first element to be inserted.
Chris@16 445 * \param end A forward iterator that points to the after-the-last element to be inserted.
Chris@16 446 * \param out An output iterator that receives results of insertion of the elements.
Chris@16 447 */
Chris@16 448 template< typename FwdIteratorT, typename OutputIteratorT >
Chris@16 449 void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out)
Chris@16 450 {
Chris@16 451 for (; begin != end; ++begin, ++out)
Chris@16 452 *out = this->insert(*begin);
Chris@16 453 }
Chris@16 454
Chris@16 455 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 456 private:
Chris@16 457 //! Constructs the object by moving from \a source_attrs. This function is mostly needed to maintain ABI stable between C++03 and C++11.
Chris@16 458 BOOST_LOG_API void construct(
Chris@16 459 attribute_value_set& source_attrs,
Chris@16 460 attribute_set const& thread_attrs,
Chris@16 461 attribute_set const& global_attrs,
Chris@16 462 size_type reserve_count);
Chris@16 463 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 464 };
Chris@16 465
Chris@16 466 /*!
Chris@16 467 * Free swap overload
Chris@16 468 */
Chris@16 469 inline void swap(attribute_value_set& left, attribute_value_set& right) BOOST_NOEXCEPT
Chris@16 470 {
Chris@16 471 left.swap(right);
Chris@16 472 }
Chris@16 473
Chris@16 474 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 475
Chris@16 476 } // namespace boost
Chris@16 477
Chris@16 478 #include <boost/log/detail/footer.hpp>
Chris@16 479
Chris@16 480 #endif // BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_