197 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			197 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								/*=============================================================================
							 | 
						||
| 
								 | 
							
								    Copyright (c) 2002-2003 Joel de Guzman
							 | 
						||
| 
								 | 
							
								    Copyright (c) 2002-2003 Martin Wille
							 | 
						||
| 
								 | 
							
								    http://spirit.sourceforge.net/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Use, modification and distribution is subject to the Boost Software
							 | 
						||
| 
								 | 
							
								    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
							 | 
						||
| 
								 | 
							
								    http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								=============================================================================*/
							 | 
						||
| 
								 | 
							
								#if !defined BOOST_SPIRIT_OBJECT_WITH_ID_IPP
							 | 
						||
| 
								 | 
							
								#define BOOST_SPIRIT_OBJECT_WITH_ID_IPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <vector>
							 | 
						||
| 
								 | 
							
								#include <boost/shared_ptr.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								#include <boost/thread/mutex.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/thread/lock_types.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/thread/once.hpp>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/spirit/home/classic/namespace.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								namespace boost { namespace spirit {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    namespace impl {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename IdT = std::size_t>
							 | 
						||
| 
								 | 
							
								        struct object_with_id_base_supply
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef IdT                     object_id;
							 | 
						||
| 
								 | 
							
								            typedef std::vector<object_id>  id_vector;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            object_with_id_base_supply() : max_id(object_id()) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								            boost::mutex        mutex;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            object_id           max_id;
							 | 
						||
| 
								 | 
							
								            id_vector           free_ids;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            object_id           acquire();
							 | 
						||
| 
								 | 
							
								            void                release(object_id);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename TagT, typename IdT = std::size_t>
							 | 
						||
| 
								 | 
							
								        struct object_with_id_base
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef TagT        tag_t;
							 | 
						||
| 
								 | 
							
								            typedef IdT         object_id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        protected:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            object_id           acquire_object_id();
							 | 
						||
| 
								 | 
							
								            void                release_object_id(object_id);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private:
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								            static boost::mutex &mutex_instance();
							 | 
						||
| 
								 | 
							
								            static void mutex_init();
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template<class TagT, typename IdT = std::size_t>
							 | 
						||
| 
								 | 
							
								        struct object_with_id : private object_with_id_base<TagT, IdT>
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            typedef object_with_id<TagT, IdT>       self_t;
							 | 
						||
| 
								 | 
							
								            typedef object_with_id_base<TagT, IdT>  base_t;
							 | 
						||
| 
								 | 
							
								            typedef IdT                             object_id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            object_with_id() : id(base_t::acquire_object_id()) {}
							 | 
						||
| 
								 | 
							
								            object_with_id(self_t const &other)
							 | 
						||
| 
								 | 
							
								                : base_t(other)
							 | 
						||
| 
								 | 
							
								                , id(base_t::acquire_object_id())
							 | 
						||
| 
								 | 
							
								            {} // don't copy id
							 | 
						||
| 
								 | 
							
								            self_t &operator = (self_t const &other)
							 | 
						||
| 
								 | 
							
								            {   // don't assign id
							 | 
						||
| 
								 | 
							
								                base_t::operator=(other);
							 | 
						||
| 
								 | 
							
								                return *this;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            ~object_with_id() { base_t::release_object_id(id); }
							 | 
						||
| 
								 | 
							
								            object_id get_object_id() const { return id; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            object_id const id;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename IdT>
							 | 
						||
| 
								 | 
							
								        inline IdT
							 | 
						||
| 
								 | 
							
								        object_with_id_base_supply<IdT>::acquire()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								            boost::unique_lock<boost::mutex> lock(mutex);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            if (free_ids.size())
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                object_id id = *free_ids.rbegin();
							 | 
						||
| 
								 | 
							
								                free_ids.pop_back();
							 | 
						||
| 
								 | 
							
								                return id;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (free_ids.capacity()<=max_id)
							 | 
						||
| 
								 | 
							
								                    free_ids.reserve(max_id*3/2+1);
							 | 
						||
| 
								 | 
							
								                return ++max_id;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename IdT>
							 | 
						||
| 
								 | 
							
								        inline void
							 | 
						||
| 
								 | 
							
								        object_with_id_base_supply<IdT>::release(IdT id)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								            boost::unique_lock<boost::mutex> lock(mutex);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            if (max_id == id)
							 | 
						||
| 
								 | 
							
								                max_id--;
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                free_ids.push_back(id); // doesn't throw
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename TagT, typename IdT>
							 | 
						||
| 
								 | 
							
								        inline IdT
							 | 
						||
| 
								 | 
							
								        object_with_id_base<TagT, IdT>::acquire_object_id()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
							 | 
						||
| 
								 | 
							
								                static boost::once_flag been_here = BOOST_ONCE_INIT;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								                static boost::once_flag been_here;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                boost::call_once(been_here, mutex_init);
							 | 
						||
| 
								 | 
							
								                boost::mutex &mutex = mutex_instance();
							 | 
						||
| 
								 | 
							
								                boost::unique_lock<boost::mutex> lock(mutex);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                static boost::shared_ptr<object_with_id_base_supply<IdT> >
							 | 
						||
| 
								 | 
							
								                    static_supply;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (!static_supply.get())
							 | 
						||
| 
								 | 
							
								                    static_supply.reset(new object_with_id_base_supply<IdT>());
							 | 
						||
| 
								 | 
							
								                id_supply = static_supply;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return id_supply->acquire();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								        template <typename TagT, typename IdT>
							 | 
						||
| 
								 | 
							
								        inline void
							 | 
						||
| 
								 | 
							
								        object_with_id_base<TagT, IdT>::release_object_id(IdT id)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            id_supply->release(id);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								        template <typename TagT, typename IdT>
							 | 
						||
| 
								 | 
							
								        inline boost::mutex &
							 | 
						||
| 
								 | 
							
								        object_with_id_base<TagT, IdT>::mutex_instance()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            static boost::mutex mutex;
							 | 
						||
| 
								 | 
							
								            return mutex;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //////////////////////////////////
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_SPIRIT_THREADSAFE
							 | 
						||
| 
								 | 
							
								        template <typename TagT, typename IdT>
							 | 
						||
| 
								 | 
							
								        inline void 
							 | 
						||
| 
								 | 
							
								        object_with_id_base<TagT, IdT>::mutex_init()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            mutex_instance();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    } // namespace impl
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								BOOST_SPIRIT_CLASSIC_NAMESPACE_END
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}} // namespace boost::spirit
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |