]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/classic/core/non_terminal/impl/static.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / classic / core / non_terminal / impl / static.hpp
1 /*=============================================================================
2 Copyright (c) 2006 Joao Abecasis
3 http://spirit.sourceforge.net/
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(BOOST_SPIRIT_STATIC_HPP)
9 #define BOOST_SPIRIT_STATIC_HPP
10
11 #include <boost/noncopyable.hpp>
12 #include <boost/call_traits.hpp>
13 #include <boost/aligned_storage.hpp>
14
15 #include <boost/type_traits/add_pointer.hpp>
16 #include <boost/type_traits/alignment_of.hpp>
17
18 #include <boost/thread/once.hpp>
19
20 #include <memory> // for placement new
21
22 #include <boost/spirit/home/classic/namespace.hpp>
23
24 namespace boost { namespace spirit {
25
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
27
28 //
29 // Provides thread-safe initialization of a single static instance of T.
30 //
31 // This instance is guaranteed to be constructed on static storage in a
32 // thread-safe manner, on the first call to the constructor of static_.
33 //
34 // Requirements:
35 // T is default constructible
36 // (There's an alternate implementation that relaxes this
37 // requirement -- Joao Abecasis)
38 // T::T() MUST not throw!
39 // this is a requirement of boost::call_once.
40 //
41 template <class T, class Tag>
42 struct static_
43 : boost::noncopyable
44 {
45 private:
46
47 struct destructor
48 {
49 ~destructor()
50 {
51 static_::get_address()->~value_type();
52 }
53 };
54
55 struct default_ctor
56 {
57 static void construct()
58 {
59 ::new (static_::get_address()) value_type();
60 static destructor d;
61 }
62 };
63
64 public:
65
66 typedef T value_type;
67 typedef typename boost::call_traits<T>::reference reference;
68 typedef typename boost::call_traits<T>::const_reference const_reference;
69
70 static_(Tag = Tag())
71 {
72 boost::call_once(&default_ctor::construct, constructed_);
73 }
74
75 operator reference()
76 {
77 return this->get();
78 }
79
80 operator const_reference() const
81 {
82 return this->get();
83 }
84
85 reference get()
86 {
87 return *this->get_address();
88 }
89
90 const_reference get() const
91 {
92 return *this->get_address();
93 }
94
95 private:
96 typedef typename boost::add_pointer<value_type>::type pointer;
97
98 static pointer get_address()
99 {
100 return static_cast<pointer>(data_.address());
101 }
102
103 typedef boost::aligned_storage<sizeof(value_type),
104 boost::alignment_of<value_type>::value> storage_type;
105
106 static storage_type data_;
107 static once_flag constructed_;
108 };
109
110 template <class T, class Tag>
111 typename static_<T, Tag>::storage_type static_<T, Tag>::data_;
112
113 template <class T, class Tag>
114 #ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
115 once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT;
116 #else
117 once_flag static_<T, Tag>::constructed_;
118 #endif
119
120 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
121
122 }} // namespace BOOST_SPIRIT_CLASSIC_NS
123
124 #endif // include guard