• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.hpp
9  * \author Andrey Semashev
10  * \date   15.04.2007
11  *
12  * The header contains attribute interface definition.
13  */
14 
15 #ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
16 #define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
17 
18 #include <new>
19 #include <boost/move/core.hpp>
20 #include <boost/smart_ptr/intrusive_ptr.hpp>
21 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
22 #include <boost/core/explicit_operator_bool.hpp>
23 #include <boost/log/detail/config.hpp>
24 #include <boost/log/detail/header.hpp>
25 
26 #ifdef BOOST_HAS_PRAGMA_ONCE
27 #pragma once
28 #endif
29 
30 namespace boost {
31 
32 BOOST_LOG_OPEN_NAMESPACE
33 
34 #ifndef BOOST_LOG_DOXYGEN_PASS
35 
36 class attribute_value;
37 
38 namespace aux {
39 
40 //! Reference proxy object to implement \c operator[]
41 class attribute_set_reference_proxy;
42 
43 } // namespace aux
44 
45 #endif // BOOST_LOG_DOXYGEN_PASS
46 
47 /*!
48  * \brief A base class for an attribute value factory
49  *
50  * Every attribute is represented with a factory that is basically an attribute value generator.
51  * The sole purpose of an attribute is to return an actual value when requested. A simplest attribute
52  * can always return the same value that it stores internally, but more complex ones can
53  * perform a considerable amount of work to return a value, and the returned values may differ
54  * each time requested.
55  *
56  * A word about thread safety. An attribute should be prepared to be requested a value from
57  * multiple threads concurrently.
58  */
59 class attribute
60 {
61     BOOST_COPYABLE_AND_MOVABLE(attribute)
62 
63 public:
64     /*!
65      * \brief A base class for an attribute value factory
66      *
67      * All attributes must derive their implementation from this class.
68      */
69     struct BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
70         public boost::intrusive_ref_counter< impl >
71     {
72         /*!
73          * \brief Virtual destructor
74          */
~implboost::attribute::impl75         virtual ~impl() {}
76 
77         /*!
78          * \return The actual attribute value. It shall not return empty values (exceptions
79          *         shall be used to indicate errors).
80          */
81         virtual attribute_value get_value() = 0;
82 
83         BOOST_LOG_API static void* operator new (std::size_t size);
84         BOOST_LOG_API static void operator delete (void* p, std::size_t size) BOOST_NOEXCEPT;
85     };
86 
87 private:
88     //! Pointer to the attribute factory implementation
89     intrusive_ptr< impl > m_pImpl;
90 
91 public:
92     /*!
93      * Default constructor. Creates an empty attribute value factory, which is not usable until
94      * \c set_impl is called.
95      */
attribute()96     BOOST_DEFAULTED_FUNCTION(attribute(), {})
97 
98     /*!
99      * Copy constructor
100      */
101     attribute(attribute const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
102 
103     /*!
104      * Move constructor
105      */
attribute(BOOST_RV_REF (attribute)that)106     attribute(BOOST_RV_REF(attribute) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
107 
108     /*!
109      * Initializing constructor
110      *
111      * \param p Pointer to the implementation. Must not be \c NULL.
112      */
attribute(intrusive_ptr<impl> p)113     explicit attribute(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
114 
115     /*!
116      * Copy assignment
117      */
operator =(BOOST_COPY_ASSIGN_REF (attribute)that)118     attribute& operator= (BOOST_COPY_ASSIGN_REF(attribute) that) BOOST_NOEXCEPT
119     {
120         m_pImpl = that.m_pImpl;
121         return *this;
122     }
123 
124     /*!
125      * Move assignment
126      */
operator =(BOOST_RV_REF (attribute)that)127     attribute& operator= (BOOST_RV_REF(attribute) that) BOOST_NOEXCEPT
128     {
129         m_pImpl.swap(that.m_pImpl);
130         return *this;
131     }
132 
133 #ifndef BOOST_LOG_DOXYGEN_PASS
134     attribute& operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT;
135 #endif
136 
137     /*!
138      * Verifies that the factory is not in empty state
139      */
140     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
141 
142     /*!
143      * Verifies that the factory is in empty state
144      */
145     bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
146 
147     /*!
148      * \return The actual attribute value. It shall not return empty values (exceptions
149      *         shall be used to indicate errors).
150      */
151     attribute_value get_value() const;
152 
153     /*!
154      * The method swaps two factories (i.e. their implementations).
155      */
swap(attribute & that)156     void swap(attribute& that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
157 
158 protected:
159     /*!
160      * \returns The pointer to the implementation
161      */
get_impl() const162     impl* get_impl() const BOOST_NOEXCEPT { return m_pImpl.get(); }
163     /*!
164      * Sets the pointer to the factory implementation.
165      *
166      * \param p Pointer to the implementation. Must not be \c NULL.
167      */
set_impl(intrusive_ptr<impl> p)168     void set_impl(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
169 
170     template< typename T >
171     friend T attribute_cast(attribute const&);
172 };
173 
174 /*!
175  * The function swaps two attribute value factories
176  */
swap(attribute & left,attribute & right)177 inline void swap(attribute& left, attribute& right) BOOST_NOEXCEPT
178 {
179     left.swap(right);
180 }
181 
182 BOOST_LOG_CLOSE_NAMESPACE // namespace log
183 
184 } // namespace boost
185 
186 #include <boost/log/detail/footer.hpp>
187 #if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_HPP_INCLUDED_)
188 #include <boost/log/detail/attribute_get_value_impl.hpp>
189 #endif
190 
191 #endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
192