diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/log/attributes/attribute_set.hpp | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/log/attributes/attribute_set.hpp')
-rw-r--r-- | boost/log/attributes/attribute_set.hpp | 507 |
1 files changed, 507 insertions, 0 deletions
diff --git a/boost/log/attributes/attribute_set.hpp b/boost/log/attributes/attribute_set.hpp new file mode 100644 index 0000000000..5481c095f4 --- /dev/null +++ b/boost/log/attributes/attribute_set.hpp @@ -0,0 +1,507 @@ +/* + * Copyright Andrey Semashev 2007 - 2014. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file attribute_set.hpp + * \author Andrey Semashev + * \date 08.03.2007 + * + * This header contains definition of the attribute set container. + */ + +#ifndef BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_ +#define BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_ + +#include <cstddef> +#include <utility> +#include <iterator> +#include <boost/mpl/if.hpp> +#include <boost/move/core.hpp> +#include <boost/log/detail/config.hpp> +#include <boost/log/attributes/attribute_name.hpp> +#include <boost/log/attributes/attribute.hpp> +#include <boost/log/detail/header.hpp> + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +BOOST_LOG_OPEN_NAMESPACE + +class attribute_set; +class attribute_value_set; + +namespace aux { + +//! Reference proxy object to implement \c operator[] +class attribute_set_reference_proxy +{ +private: + //! Key type + typedef attribute_name key_type; + //! Mapped attribute type + typedef attribute mapped_type; + +private: + attribute_set* const m_pContainer; + const key_type m_key; + +public: + //! Constructor + explicit attribute_set_reference_proxy(attribute_set* pContainer, key_type const& key) BOOST_NOEXCEPT : + m_pContainer(pContainer), + m_key(key) + { + } + + //! Conversion operator (would be invoked in case of reading from the container) + operator mapped_type() const BOOST_NOEXCEPT; + //! Assignment operator (would be invoked in case of writing to the container) + mapped_type& operator= (mapped_type const& val) const; +}; + +} // namespace aux + +/*! + * \brief An attribute set class. + * + * An attribute set is an associative container with attribute name as a key and + * pointer to the attribute as a mapped value. The container allows storing only one element for each distinct + * key value. In most regards attribute set container provides interface similar to \c std::unordered_map. + * However, there are differences in \c operator[] semantics and a number of optimizations with regard to iteration. + * Besides, attribute names are stored as a read-only <tt>attribute_name</tt>'s instead of \c std::string, + * which saves memory and CPU time. + */ +class attribute_set +{ + BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_set) + + friend class attribute_value_set; + friend class aux::attribute_set_reference_proxy; + +public: + //! Key type + typedef attribute_name key_type; + //! Mapped attribute type + typedef attribute mapped_type; + + //! Value type + typedef std::pair< const key_type, mapped_type > value_type; + //! Reference type + typedef value_type& reference; + //! Const reference type + typedef value_type const& const_reference; + //! Pointer type + typedef value_type* pointer; + //! Const pointer type + typedef value_type const* const_pointer; + //! Size type + typedef std::size_t size_type; + //! Difference type + typedef std::ptrdiff_t difference_type; + +private: + //! \cond + + //! Implementation + struct implementation; + friend struct implementation; + + //! A base class for the container nodes + struct node_base + { + node_base* m_pPrev; + node_base* m_pNext; + + node_base(); + + BOOST_DELETED_FUNCTION(node_base(node_base const&)) + BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&)) + }; + + //! Container elements + struct node; + friend struct node; + struct node : + public node_base + { + value_type m_Value; + + node(key_type const& key, mapped_type const& data); + }; + + //! Iterator class +#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS + template< bool fConstV > class iter; + template< bool fConstV > friend class iter; +#endif + template< bool fConstV > + class iter + { + friend class iter< !fConstV >; + friend class attribute_set; + + public: + // Standard typedefs + typedef attribute_set::difference_type difference_type; + typedef attribute_set::value_type value_type; + typedef typename mpl::if_c< + fConstV, + attribute_set::const_reference, + attribute_set::reference + >::type reference; + typedef typename mpl::if_c< + fConstV, + attribute_set::const_pointer, + attribute_set::pointer + >::type pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + public: + // Constructors + BOOST_CONSTEXPR iter() : m_pNode(NULL) {} + explicit iter(node_base* pNode) BOOST_NOEXCEPT : m_pNode(pNode) {} + iter(iter< false > const& that) BOOST_NOEXCEPT : m_pNode(that.m_pNode) {} + + //! Assignment + template< bool f > + iter& operator= (iter< f > const& that) BOOST_NOEXCEPT + { + m_pNode = that.m_pNode; + return *this; + } + + // Comparison + template< bool f > + bool operator== (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode == that.m_pNode); } + template< bool f > + bool operator!= (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode != that.m_pNode); } + + // Modification + iter& operator++ () BOOST_NOEXCEPT + { + m_pNode = m_pNode->m_pNext; + return *this; + } + iter& operator-- () BOOST_NOEXCEPT + { + m_pNode = m_pNode->m_pPrev; + return *this; + } + iter operator++ (int) BOOST_NOEXCEPT + { + iter tmp(*this); + m_pNode = m_pNode->m_pNext; + return tmp; + } + iter operator-- (int) BOOST_NOEXCEPT + { + iter tmp(*this); + m_pNode = m_pNode->m_pPrev; + return tmp; + } + + // Dereferencing + pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); } + reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; } + + node_base* base() const BOOST_NOEXCEPT { return m_pNode; } + + private: + node_base* m_pNode; + }; + + //! \endcond + +public: +#ifndef BOOST_LOG_DOXYGEN_PASS + //! Iterator type + typedef iter< false > iterator; + //! Const iterator type + typedef iter< true > const_iterator; +#else + /*! + * Iterator type. The iterator complies to the bidirectional iterator requirements. + */ + typedef implementation_defined iterator; + /*! + * Constant iterator type. The iterator complies to the bidirectional iterator requirements with read-only capabilities. + */ + typedef implementation_defined const_iterator; +#endif // BOOST_LOG_DOXYGEN_PASS + +private: + //! Pointer to implementation + implementation* m_pImpl; + +public: + /*! + * Default constructor. + * + * \post <tt>empty() == true</tt> + */ + BOOST_LOG_API attribute_set(); + + /*! + * Copy constructor. + * + * \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt> + */ + BOOST_LOG_API attribute_set(attribute_set const& that); + + /*! + * Move constructor + */ + attribute_set(BOOST_RV_REF(attribute_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) + { + that.m_pImpl = NULL; + } + + /*! + * Destructor. All stored references to attributes are released. + */ + BOOST_LOG_API ~attribute_set() BOOST_NOEXCEPT; + + /*! + * Copy assignment operator. + * + * \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt> + */ + attribute_set& operator= (attribute_set that) BOOST_NOEXCEPT + { + this->swap(that); + return *this; + } + + /*! + * Swaps two instances of the container. + * + * \b Throws: Nothing. + */ + void swap(attribute_set& that) BOOST_NOEXCEPT + { + implementation* const p = m_pImpl; + m_pImpl = that.m_pImpl; + that.m_pImpl = p; + } + + /*! + * \return Iterator to the first element of the container. + */ + BOOST_LOG_API iterator begin() BOOST_NOEXCEPT; + /*! + * \return Iterator to the after-the-last element of the container. + */ + BOOST_LOG_API iterator end() BOOST_NOEXCEPT; + /*! + * \return Constant iterator to the first element of the container. + */ + BOOST_LOG_API const_iterator begin() const BOOST_NOEXCEPT; + /*! + * \return Constant iterator to the after-the-last element of the container. + */ + BOOST_LOG_API const_iterator end() const BOOST_NOEXCEPT; + + /*! + * \return Number of elements in the container. + */ + BOOST_LOG_API size_type size() const BOOST_NOEXCEPT; + /*! + * \return true if there are no elements in the container, false otherwise. + */ + bool empty() const BOOST_NOEXCEPT { return (this->size() == 0); } + + /*! + * The method finds the attribute by name. + * + * \param key Attribute name. + * \return Iterator to the found element or end() if the attribute with such name is not found. + */ + BOOST_LOG_API iterator find(key_type key) BOOST_NOEXCEPT; + /*! + * The method finds the attribute by name. + * + * \param key Attribute name. + * \return Iterator to the found element or \c end() if the attribute with such name is not found. + */ + const_iterator find(key_type key) const BOOST_NOEXCEPT + { + return const_iterator(const_cast< attribute_set* >(this)->find(key)); + } + /*! + * The method counts the number of the attribute occurrences in the container. Since there can be only one + * attribute with a particular key, the method always return 0 or 1. + * + * \param key Attribute name. + * \return The number of times the attribute is found in the container. + */ + size_type count(key_type key) const BOOST_NOEXCEPT { return size_type(this->find(key) != this->end()); } + + /*! + * Combined lookup/insertion operator. The operator semantics depends on the further usage of the returned reference. + * \li If the reference is used as an assignment target, the assignment expression is equivalent to element insertion, + * where the element is composed of the second argument of the \c operator[] as a key and the second argument of assignment + * as a mapped value. + * \li If the returned reference is used in context where a conversion to the mapped type is required, + * the result of the conversion is equivalent to the mapped value found with the second argument of the \c operator[] as a key, + * if such an element exists in the container, or a default-constructed mapped value, if an element does not exist in the + * container. + * + * \param key Attribute name. + * \return A smart reference object of unspecified type. + */ + aux::attribute_set_reference_proxy operator[] (key_type key) BOOST_NOEXCEPT + { + return aux::attribute_set_reference_proxy(this, key); + } + /*! + * Lookup operator + * + * \param key Attribute name. + * \return If an element with the corresponding attribute name is found in the container, its mapped value + * is returned. Otherwise a default-constructed mapped value is returned. + */ + mapped_type operator[] (key_type key) const BOOST_NOEXCEPT + { + const_iterator it = this->find(key); + if (it != end()) + return it->second; + else + return mapped_type(); + } + + /*! + * Insertion method + * + * \param key Attribute name. + * \param data Pointer to the attribute. Must not be NULL. + * \returns A pair of values. If second is true, the insertion succeeded and the first component points to the + * inserted element. Otherwise the first component points to the element that prevents insertion. + */ + BOOST_LOG_API std::pair< iterator, bool > insert(key_type key, mapped_type const& data); + + /*! + * Insertion method + * + * \param value An element to be inserted. + * \returns A pair of values. If second is true, the insertion succeeded and the first component points to the + * inserted element. Otherwise the first component points to the element that prevents insertion. + */ + std::pair< iterator, bool > insert(const_reference value) + { + return this->insert(value.first, value.second); + } + + /*! + * Mass insertion method. + * + * \param begin A forward iterator that points to the first element to be inserted. + * \param end A forward iterator that points to the after-the-last element to be inserted. + */ + template< typename FwdIteratorT > + void insert(FwdIteratorT begin, FwdIteratorT end) + { + for (; begin != end; ++begin) + this->insert(*begin); + } + + /*! + * Mass insertion method with ability to acquire iterators to the inserted elements. + * + * \param begin A forward iterator that points to the first element to be inserted. + * \param end A forward iterator that points to the after-the-last element to be inserted. + * \param out An output iterator that receives results of insertion of the elements + */ + template< typename FwdIteratorT, typename OutputIteratorT > + void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out) + { + for (; begin != end; ++begin, ++out) + *out = this->insert(*begin); + } + + /*! + * The method erases all attributes with the specified name + * + * \post All iterators to the erased elements become invalid. + * \param key Attribute name. + * \return Tne number of erased elements + */ + BOOST_LOG_API size_type erase(key_type key) BOOST_NOEXCEPT; + /*! + * The method erases the specified attribute + * + * \post All iterators to the erased element become invalid. + * \param it A valid iterator to the element to be erased. + * \return Tne number of erased elements + */ + BOOST_LOG_API void erase(iterator it) BOOST_NOEXCEPT; + /*! + * The method erases all attributes within the specified range + * + * \pre \a end is reachable from \a begin with a finite number of increments. + * \post All iterators to the erased elements become invalid. + * \param begin An iterator that points to the first element to be erased. + * \param end An iterator that points to the after-the-last element to be erased. + */ + BOOST_LOG_API void erase(iterator begin, iterator end) BOOST_NOEXCEPT; + + /*! + * The method removes all elements from the container + * + * \post <tt>empty() == true</tt> + */ + BOOST_LOG_API void clear() BOOST_NOEXCEPT; +}; + +/*! + * Free swap overload + */ +inline void swap(attribute_set& left, attribute_set& right) BOOST_NOEXCEPT +{ + left.swap(right); +} + +namespace aux { + +//! Conversion operator (would be invoked in case of reading from the container) +inline attribute_set_reference_proxy::operator mapped_type() const BOOST_NOEXCEPT +{ + attribute_set::iterator it = m_pContainer->find(m_key); + if (it != m_pContainer->end()) + return it->second; + else + return mapped_type(); +} + +//! Assignment operator (would be invoked in case of writing to the container) +inline attribute_set_reference_proxy::mapped_type& attribute_set_reference_proxy::operator= (mapped_type const& val) const +{ + std::pair< attribute_set::iterator, bool > res = m_pContainer->insert(m_key, val); + if (!res.second) + res.first->second = val; + return res.first->second; +} + +} // namespace aux + +#ifndef BOOST_LOG_DOXYGEN_PASS +inline attribute& attribute::operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT +{ + attribute attr = that; + this->swap(attr); + return *this; +} +#endif + +BOOST_LOG_CLOSE_NAMESPACE // namespace log + +} // namespace boost + +#include <boost/log/detail/footer.hpp> + +#endif // BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_ |