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