]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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/log/detail/config.hpp> | |
23 | #include <boost/utility/explicit_operator_bool.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 | */ | |
75 | 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 | */ | |
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 | */ | |
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 | */ | |
113 | explicit attribute(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); } | |
114 | ||
115 | /*! | |
116 | * Copy assignment | |
117 | */ | |
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 | */ | |
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 | */ | |
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 | */ | |
162 | 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 | */ | |
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 | */ | |
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_ |