]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / core / non_terminal / impl / object_with_id.ipp
1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Martin Wille
4 http://spirit.sourceforge.net/
5
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #if !defined BOOST_SPIRIT_OBJECT_WITH_ID_IPP
11 #define BOOST_SPIRIT_OBJECT_WITH_ID_IPP
12
13 #include <vector>
14 #include <boost/shared_ptr.hpp>
15
16 #ifdef BOOST_SPIRIT_THREADSAFE
17 #include <boost/thread/mutex.hpp>
18 #include <boost/thread/lock_types.hpp>
19 #include <boost/thread/once.hpp>
20 #endif
21
22 #include <boost/spirit/home/classic/namespace.hpp>
23
24 ///////////////////////////////////////////////////////////////////////////////
25 namespace boost { namespace spirit {
26
27 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
28
29 namespace impl {
30
31 //////////////////////////////////
32 template <typename IdT = std::size_t>
33 struct object_with_id_base_supply
34 {
35 typedef IdT object_id;
36 typedef std::vector<object_id> id_vector;
37
38 object_with_id_base_supply() : max_id(object_id()) {}
39
40 #ifdef BOOST_SPIRIT_THREADSAFE
41 boost::mutex mutex;
42 #endif
43 object_id max_id;
44 id_vector free_ids;
45
46 object_id acquire();
47 void release(object_id);
48 };
49
50 //////////////////////////////////
51 template <typename TagT, typename IdT = std::size_t>
52 struct object_with_id_base
53 {
54 typedef TagT tag_t;
55 typedef IdT object_id;
56
57 protected:
58
59 object_id acquire_object_id();
60 void release_object_id(object_id);
61
62 private:
63 #ifdef BOOST_SPIRIT_THREADSAFE
64 static boost::mutex &mutex_instance();
65 static void mutex_init();
66 #endif
67
68 boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply;
69 };
70
71 //////////////////////////////////
72 template<class TagT, typename IdT = std::size_t>
73 struct object_with_id : private object_with_id_base<TagT, IdT>
74 {
75 typedef object_with_id<TagT, IdT> self_t;
76 typedef object_with_id_base<TagT, IdT> base_t;
77 typedef IdT object_id;
78
79 object_with_id() : id(base_t::acquire_object_id()) {}
80 object_with_id(self_t const &other)
81 : base_t(other)
82 , id(base_t::acquire_object_id())
83 {} // don't copy id
84 self_t &operator = (self_t const &other)
85 { // don't assign id
86 base_t::operator=(other);
87 return *this;
88 }
89 ~object_with_id() { base_t::release_object_id(id); }
90 object_id get_object_id() const { return id; }
91
92 private:
93
94 object_id const id;
95 };
96
97 //////////////////////////////////
98 template <typename IdT>
99 inline IdT
100 object_with_id_base_supply<IdT>::acquire()
101 {
102 #ifdef BOOST_SPIRIT_THREADSAFE
103 boost::unique_lock<boost::mutex> lock(mutex);
104 #endif
105 if (free_ids.size())
106 {
107 object_id id = *free_ids.rbegin();
108 free_ids.pop_back();
109 return id;
110 }
111 else
112 {
113 if (free_ids.capacity()<=max_id)
114 free_ids.reserve(max_id*3/2+1);
115 return ++max_id;
116 }
117 }
118
119 //////////////////////////////////
120 template <typename IdT>
121 inline void
122 object_with_id_base_supply<IdT>::release(IdT id)
123 {
124 #ifdef BOOST_SPIRIT_THREADSAFE
125 boost::unique_lock<boost::mutex> lock(mutex);
126 #endif
127 if (max_id == id)
128 max_id--;
129 else
130 free_ids.push_back(id); // doesn't throw
131 }
132
133 //////////////////////////////////
134 template <typename TagT, typename IdT>
135 inline IdT
136 object_with_id_base<TagT, IdT>::acquire_object_id()
137 {
138 {
139 #ifdef BOOST_SPIRIT_THREADSAFE
140 #ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
141 static boost::once_flag been_here = BOOST_ONCE_INIT;
142 #else
143 static boost::once_flag been_here;
144 #endif
145 boost::call_once(been_here, mutex_init);
146 boost::mutex &mutex = mutex_instance();
147 boost::unique_lock<boost::mutex> lock(mutex);
148 #endif
149 static boost::shared_ptr<object_with_id_base_supply<IdT> >
150 static_supply;
151
152 if (!static_supply.get())
153 static_supply.reset(new object_with_id_base_supply<IdT>());
154 id_supply = static_supply;
155 }
156
157 return id_supply->acquire();
158 }
159
160 //////////////////////////////////
161 template <typename TagT, typename IdT>
162 inline void
163 object_with_id_base<TagT, IdT>::release_object_id(IdT id)
164 {
165 id_supply->release(id);
166 }
167
168 //////////////////////////////////
169 #ifdef BOOST_SPIRIT_THREADSAFE
170 template <typename TagT, typename IdT>
171 inline boost::mutex &
172 object_with_id_base<TagT, IdT>::mutex_instance()
173 {
174 static boost::mutex mutex;
175 return mutex;
176 }
177 #endif
178
179 //////////////////////////////////
180 #ifdef BOOST_SPIRIT_THREADSAFE
181 template <typename TagT, typename IdT>
182 inline void
183 object_with_id_base<TagT, IdT>::mutex_init()
184 {
185 mutex_instance();
186 }
187 #endif
188
189 } // namespace impl
190
191 ///////////////////////////////////////////////////////////////////////////////
192 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
193
194 }} // namespace boost::spirit
195
196 #endif