1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Martin Wille
4 http://spirit.sourceforge.net/
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
14 #include <boost/shared_ptr.hpp>
16 #ifdef BOOST_SPIRIT_THREADSAFE
17 #include <boost/thread/mutex.hpp>
18 #include <boost/thread/once.hpp>
21 #include <boost/spirit/home/classic/namespace.hpp>
23 ///////////////////////////////////////////////////////////////////////////////
24 namespace boost { namespace spirit {
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
30 //////////////////////////////////
31 template <typename IdT = std::size_t>
32 struct object_with_id_base_supply
34 typedef IdT object_id;
35 typedef std::vector<object_id> id_vector;
37 object_with_id_base_supply() : max_id(object_id()) {}
39 #ifdef BOOST_SPIRIT_THREADSAFE
46 void release(object_id);
49 //////////////////////////////////
50 template <typename TagT, typename IdT = std::size_t>
51 struct object_with_id_base
54 typedef IdT object_id;
58 object_id acquire_object_id();
59 void release_object_id(object_id);
62 #ifdef BOOST_SPIRIT_THREADSAFE
63 static boost::mutex &mutex_instance();
64 static void mutex_init();
67 boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply;
70 //////////////////////////////////
71 template<class TagT, typename IdT = std::size_t>
72 struct object_with_id : private object_with_id_base<TagT, IdT>
74 typedef object_with_id<TagT, IdT> self_t;
75 typedef object_with_id_base<TagT, IdT> base_t;
76 typedef IdT object_id;
78 object_with_id() : id(base_t::acquire_object_id()) {}
79 object_with_id(self_t const &other)
81 , id(base_t::acquire_object_id())
83 self_t &operator = (self_t const &other)
85 base_t::operator=(other);
88 ~object_with_id() { base_t::release_object_id(id); }
89 object_id get_object_id() const { return id; }
96 //////////////////////////////////
97 template <typename IdT>
99 object_with_id_base_supply<IdT>::acquire()
101 #ifdef BOOST_SPIRIT_THREADSAFE
102 boost::mutex::scoped_lock lock(mutex);
106 object_id id = *free_ids.rbegin();
112 if (free_ids.capacity()<=max_id)
113 free_ids.reserve(max_id*3/2+1);
118 //////////////////////////////////
119 template <typename IdT>
121 object_with_id_base_supply<IdT>::release(IdT id)
123 #ifdef BOOST_SPIRIT_THREADSAFE
124 boost::mutex::scoped_lock lock(mutex);
129 free_ids.push_back(id); // doesn't throw
132 //////////////////////////////////
133 template <typename TagT, typename IdT>
135 object_with_id_base<TagT, IdT>::acquire_object_id()
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);
144 static boost::shared_ptr<object_with_id_base_supply<IdT> >
147 if (!static_supply.get())
148 static_supply.reset(new object_with_id_base_supply<IdT>());
149 id_supply = static_supply;
152 return id_supply->acquire();
155 //////////////////////////////////
156 template <typename TagT, typename IdT>
158 object_with_id_base<TagT, IdT>::release_object_id(IdT id)
160 id_supply->release(id);
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()
169 static boost::mutex mutex;
174 //////////////////////////////////
175 #ifdef BOOST_SPIRIT_THREADSAFE
176 template <typename TagT, typename IdT>
178 object_with_id_base<TagT, IdT>::mutex_init()
186 ///////////////////////////////////////////////////////////////////////////////
187 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
189 }} // namespace boost::spirit
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