Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/log/detail/locking_ptr.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /* | |
2 * Copyright Andrey Semashev 2007 - 2013. | |
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 locking_ptr.hpp | |
9 * \author Andrey Semashev | |
10 * \date 15.07.2009 | |
11 * | |
12 * This header is the Boost.Log library implementation, see the library documentation | |
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. | |
14 */ | |
15 | |
16 #ifndef BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_ | |
17 #define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_ | |
18 | |
19 #include <boost/smart_ptr/shared_ptr.hpp> | |
20 #include <boost/log/detail/config.hpp> | |
21 #include <boost/utility/explicit_operator_bool.hpp> | |
22 #include <boost/log/detail/header.hpp> | |
23 | |
24 #ifdef BOOST_HAS_PRAGMA_ONCE | |
25 #pragma once | |
26 #endif | |
27 | |
28 namespace boost { | |
29 | |
30 BOOST_LOG_OPEN_NAMESPACE | |
31 | |
32 namespace aux { | |
33 | |
34 //! Shared lock object to support locking_ptr | |
35 struct BOOST_LOG_NO_VTABLE locking_ptr_counter_base | |
36 { | |
37 unsigned int m_RefCounter; | |
38 | |
39 locking_ptr_counter_base() : m_RefCounter(0) | |
40 { | |
41 } | |
42 | |
43 virtual ~locking_ptr_counter_base() {} | |
44 virtual void lock() = 0; | |
45 virtual bool try_lock() = 0; | |
46 virtual void unlock() = 0; | |
47 | |
48 private: | |
49 locking_ptr_counter_base(locking_ptr_counter_base const&); | |
50 locking_ptr_counter_base& operator= (locking_ptr_counter_base const&); | |
51 }; | |
52 | |
53 struct try_lock_tag {}; | |
54 BOOST_CONSTEXPR_OR_CONST try_lock_tag try_lock = {}; | |
55 | |
56 //! A pointer type that locks the backend until it's destroyed | |
57 template< typename T > | |
58 class locking_ptr | |
59 { | |
60 public: | |
61 //! Pointed type | |
62 typedef T element_type; | |
63 | |
64 private: | |
65 //! The pointer to the backend | |
66 shared_ptr< element_type > m_pElement; | |
67 //! Reference to the shared lock control object | |
68 locking_ptr_counter_base* m_pLock; | |
69 | |
70 public: | |
71 //! Constructor | |
72 locking_ptr(shared_ptr< element_type > const& p, locking_ptr_counter_base& l) | |
73 : m_pElement(p), m_pLock(&l) | |
74 { | |
75 if (m_pLock->m_RefCounter == 0) | |
76 m_pLock->lock(); | |
77 ++m_pLock->m_RefCounter; | |
78 } | |
79 //! Constructor | |
80 locking_ptr(shared_ptr< element_type > const& p, locking_ptr_counter_base& l, try_lock_tag const&) | |
81 : m_pElement(p), m_pLock(&l) | |
82 { | |
83 if (m_pLock->m_RefCounter > 0 || m_pLock->try_lock()) | |
84 { | |
85 ++m_pLock->m_RefCounter; | |
86 } | |
87 else | |
88 { | |
89 m_pElement.reset(); | |
90 m_pLock = NULL; | |
91 } | |
92 } | |
93 //! Copy constructor | |
94 locking_ptr(locking_ptr const& that) : m_pElement(that.m_pElement), m_pLock(that.m_pLock) | |
95 { | |
96 if (m_pLock) | |
97 ++m_pLock->m_RefCounter; | |
98 } | |
99 //! Destructor | |
100 ~locking_ptr() | |
101 { | |
102 if (m_pLock && --m_pLock->m_RefCounter == 0) | |
103 m_pLock->unlock(); | |
104 } | |
105 | |
106 //! Assignment | |
107 locking_ptr& operator= (locking_ptr that) | |
108 { | |
109 this->swap(that); | |
110 return *this; | |
111 } | |
112 | |
113 //! Indirection | |
114 element_type* operator-> () const { return m_pElement.get(); } | |
115 //! Dereferencing | |
116 element_type& operator* () const { return *m_pElement; } | |
117 | |
118 //! Accessor to the raw pointer | |
119 element_type* get() const { return m_pElement.get(); } | |
120 | |
121 //! Checks for null pointer | |
122 BOOST_EXPLICIT_OPERATOR_BOOL() | |
123 //! Checks for null pointer | |
124 bool operator! () const { return !m_pElement; } | |
125 | |
126 //! Swaps two pointers | |
127 void swap(locking_ptr& that) | |
128 { | |
129 m_pElement.swap(that.m_pElement); | |
130 register locking_ptr_counter_base* p = m_pLock; | |
131 m_pLock = that.m_pLock; | |
132 that.m_pLock = p; | |
133 } | |
134 }; | |
135 | |
136 //! Free raw pointer getter to assist generic programming | |
137 template< typename T > | |
138 inline T* get_pointer(locking_ptr< T > const& p) | |
139 { | |
140 return p.get(); | |
141 } | |
142 //! Free swap operation | |
143 template< typename T > | |
144 inline void swap(locking_ptr< T >& left, locking_ptr< T >& right) | |
145 { | |
146 left.swap(right); | |
147 } | |
148 | |
149 } // namespace aux | |
150 | |
151 BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
152 | |
153 } // namespace boost | |
154 | |
155 #include <boost/log/detail/footer.hpp> | |
156 | |
157 #endif // BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_ |