125 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
/*=============================================================================
 | 
						|
    Copyright (c) 2006 Joao Abecasis
 | 
						|
    http://spirit.sourceforge.net/
 | 
						|
 | 
						|
  Distributed under 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_STATIC_HPP)
 | 
						|
#define BOOST_SPIRIT_STATIC_HPP
 | 
						|
 | 
						|
#include <boost/noncopyable.hpp>
 | 
						|
#include <boost/call_traits.hpp>
 | 
						|
#include <boost/aligned_storage.hpp>
 | 
						|
 | 
						|
#include <boost/type_traits/add_pointer.hpp>
 | 
						|
#include <boost/type_traits/alignment_of.hpp>
 | 
						|
 | 
						|
#include <boost/thread/once.hpp>
 | 
						|
 | 
						|
#include <memory>   // for placement new
 | 
						|
 | 
						|
#include <boost/spirit/home/classic/namespace.hpp>
 | 
						|
 | 
						|
namespace boost { namespace spirit {
 | 
						|
 | 
						|
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
 | 
						|
 | 
						|
    //
 | 
						|
    //  Provides thread-safe initialization of a single static instance of T.
 | 
						|
    //
 | 
						|
    //  This instance is guaranteed to be constructed on static storage in a
 | 
						|
    //  thread-safe manner, on the first call to the constructor of static_.
 | 
						|
    //
 | 
						|
    //  Requirements:
 | 
						|
    //      T is default constructible
 | 
						|
    //          (There's an alternate implementation that relaxes this
 | 
						|
    //              requirement -- Joao Abecasis)
 | 
						|
    //      T::T() MUST not throw!
 | 
						|
    //          this is a requirement of boost::call_once.
 | 
						|
    //
 | 
						|
    template <class T, class Tag>
 | 
						|
    struct static_
 | 
						|
        : boost::noncopyable
 | 
						|
    {
 | 
						|
    private:
 | 
						|
 | 
						|
        struct destructor
 | 
						|
        {
 | 
						|
            ~destructor()
 | 
						|
            {
 | 
						|
                static_::get_address()->~value_type();
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        struct default_ctor
 | 
						|
        {
 | 
						|
            static void construct()
 | 
						|
            {
 | 
						|
                ::new (static_::get_address()) value_type();
 | 
						|
                static destructor d;
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
    public:
 | 
						|
 | 
						|
        typedef T value_type;
 | 
						|
        typedef typename boost::call_traits<T>::reference reference;
 | 
						|
        typedef typename boost::call_traits<T>::const_reference const_reference;
 | 
						|
 | 
						|
        static_(Tag = Tag())
 | 
						|
        {
 | 
						|
            boost::call_once(&default_ctor::construct, constructed_);
 | 
						|
        }
 | 
						|
 | 
						|
        operator reference()
 | 
						|
        {
 | 
						|
            return this->get();
 | 
						|
        }
 | 
						|
 | 
						|
        operator const_reference() const
 | 
						|
        {
 | 
						|
            return this->get();
 | 
						|
        }
 | 
						|
 | 
						|
        reference get()
 | 
						|
        {
 | 
						|
            return *this->get_address();
 | 
						|
        }
 | 
						|
 | 
						|
        const_reference get() const
 | 
						|
        {
 | 
						|
            return *this->get_address();
 | 
						|
        }
 | 
						|
 | 
						|
    private:
 | 
						|
        typedef typename boost::add_pointer<value_type>::type pointer;
 | 
						|
 | 
						|
        static pointer get_address()
 | 
						|
        {
 | 
						|
            return static_cast<pointer>(data_.address());
 | 
						|
        }
 | 
						|
 | 
						|
        typedef boost::aligned_storage<sizeof(value_type),
 | 
						|
            boost::alignment_of<value_type>::value> storage_type;
 | 
						|
 | 
						|
        static storage_type data_;
 | 
						|
        static once_flag constructed_;
 | 
						|
    };
 | 
						|
 | 
						|
    template <class T, class Tag>
 | 
						|
    typename static_<T, Tag>::storage_type static_<T, Tag>::data_;
 | 
						|
 | 
						|
    template <class T, class Tag>
 | 
						|
#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
 | 
						|
    once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT;
 | 
						|
#else
 | 
						|
    once_flag static_<T, Tag>::constructed_;
 | 
						|
#endif
 | 
						|
 | 
						|
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
 | 
						|
 | 
						|
}} // namespace BOOST_SPIRIT_CLASSIC_NS
 | 
						|
 | 
						|
#endif // include guard
 |