summaryrefslogtreecommitdiff
path: root/boost/log/attributes/attribute_set.hpp
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
committerChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
commit08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch)
tree7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/log/attributes/attribute_set.hpp
parentbb4dd8289b351fae6b55e303f189127a394a1edd (diff)
downloadboost-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.hpp507
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_