]> https://gitweb.dealii.org/ - dealii-svn.git/blob
822180a97776e152b7b5de8103f304c624cfaa2b
[dealii-svn.git] /
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/once.hpp>
19 #endif
20
21 #include <boost/spirit/home/classic/namespace.hpp>
22
23 ///////////////////////////////////////////////////////////////////////////////
24 namespace boost { namespace spirit {
25
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
27
28     namespace impl {
29
30         //////////////////////////////////
31         template <typename IdT = std::size_t>
32         struct object_with_id_base_supply
33         {
34             typedef IdT                     object_id;
35             typedef std::vector<object_id>  id_vector;
36
37             object_with_id_base_supply() : max_id(object_id()) {}
38
39 #ifdef BOOST_SPIRIT_THREADSAFE
40             boost::mutex        mutex;
41 #endif
42             object_id           max_id;
43             id_vector           free_ids;
44
45             object_id           acquire();
46             void                release(object_id);
47         };
48
49         //////////////////////////////////
50         template <typename TagT, typename IdT = std::size_t>
51         struct object_with_id_base
52         {
53             typedef TagT        tag_t;
54             typedef IdT         object_id;
55
56         protected:
57
58             object_id           acquire_object_id();
59             void                release_object_id(object_id);
60
61         private:
62 #ifdef BOOST_SPIRIT_THREADSAFE
63             static boost::mutex &mutex_instance();
64             static void mutex_init();
65 #endif
66
67             boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply;
68         };
69
70         //////////////////////////////////
71         template<class TagT, typename IdT = std::size_t>
72         struct object_with_id : private object_with_id_base<TagT, IdT>
73         {
74             typedef object_with_id<TagT, IdT>       self_t;
75             typedef object_with_id_base<TagT, IdT>  base_t;
76             typedef IdT                             object_id;
77
78             object_with_id() : id(base_t::acquire_object_id()) {}
79             object_with_id(self_t const &other)
80                 : base_t(other)
81                 , id(base_t::acquire_object_id())
82             {} // don't copy id
83             self_t &operator = (self_t const &other)
84             {   // don't assign id
85                 base_t::operator=(other);
86                 return *this;
87             }
88             ~object_with_id() { base_t::release_object_id(id); }
89             object_id get_object_id() const { return id; }
90
91         private:
92
93             object_id const id;
94         };
95
96         //////////////////////////////////
97         template <typename IdT>
98         inline IdT
99         object_with_id_base_supply<IdT>::acquire()
100         {
101 #ifdef BOOST_SPIRIT_THREADSAFE
102             boost::mutex::scoped_lock lock(mutex);
103 #endif
104             if (free_ids.size())
105             {
106                 object_id id = *free_ids.rbegin();
107                 free_ids.pop_back();
108                 return id;
109             }
110             else
111             {
112                 if (free_ids.capacity()<=max_id)
113                     free_ids.reserve(max_id*3/2+1);
114                 return ++max_id;
115             }
116         }
117
118         //////////////////////////////////
119         template <typename IdT>
120         inline void
121         object_with_id_base_supply<IdT>::release(IdT id)
122         {
123 #ifdef BOOST_SPIRIT_THREADSAFE
124             boost::mutex::scoped_lock lock(mutex);
125 #endif
126             if (max_id == id)
127                 max_id--;
128             else
129                 free_ids.push_back(id); // doesn't throw
130         }
131
132         //////////////////////////////////
133         template <typename TagT, typename IdT>
134         inline IdT
135         object_with_id_base<TagT, IdT>::acquire_object_id()
136         {
137             {
138 #ifdef BOOST_SPIRIT_THREADSAFE
139                 static boost::once_flag been_here = BOOST_ONCE_INIT;
140                 boost::call_once(been_here, mutex_init);
141                 boost::mutex &mutex = mutex_instance();
142                 boost::mutex::scoped_lock lock(mutex);
143 #endif
144                 static boost::shared_ptr<object_with_id_base_supply<IdT> >
145                     static_supply;
146
147                 if (!static_supply.get())
148                     static_supply.reset(new object_with_id_base_supply<IdT>());
149                 id_supply = static_supply;
150             }
151
152             return id_supply->acquire();
153         }
154
155         //////////////////////////////////
156         template <typename TagT, typename IdT>
157         inline void
158         object_with_id_base<TagT, IdT>::release_object_id(IdT id)
159         {
160             id_supply->release(id);
161         }
162
163         //////////////////////////////////
164 #ifdef BOOST_SPIRIT_THREADSAFE
165         template <typename TagT, typename IdT>
166         inline boost::mutex &
167         object_with_id_base<TagT, IdT>::mutex_instance()
168         {
169             static boost::mutex mutex;
170             return mutex;
171         }
172 #endif
173
174         //////////////////////////////////
175 #ifdef BOOST_SPIRIT_THREADSAFE
176         template <typename TagT, typename IdT>
177         inline void 
178         object_with_id_base<TagT, IdT>::mutex_init()
179         {
180             mutex_instance();
181         }
182 #endif
183
184     } // namespace impl
185
186 ///////////////////////////////////////////////////////////////////////////////
187 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
188
189 }} // namespace boost::spirit
190
191 #endif

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.