Initial Commit
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
Reference in New Issue
Block a user