PageRenderTime 42ms CodeModel.GetById 39ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp

http://hadesmem.googlecode.com/
C++ Header | 191 lines | 140 code | 31 blank | 20 comment | 5 complexity | cf8860d39b53fd950b6fca3a68d37530 MD5 | raw file
  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///////////////////////////////////////////////////////////////////////////////
 24namespace boost { namespace spirit {
 25
 26BOOST_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///////////////////////////////////////////////////////////////////////////////
187BOOST_SPIRIT_CLASSIC_NAMESPACE_END
188
189}} // namespace boost::spirit
190
191#endif