Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/container/detail/singleton.hpp @ 102:f46d142149f5
Whoops, finish that update
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:13:41 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
101:c530137014c0 | 102:f46d142149f5 |
---|---|
1 // Copyright (C) 2000 Stephen Cleary | |
2 // Copyright (C) 2008 Ion Gaztanaga | |
3 // | |
4 // Distributed under the Boost Software License, Version 1.0. (See | |
5 // accompanying file LICENSE_1_0.txt or copy at | |
6 // http://www.boost.org/LICENSE_1_0.txt) | |
7 // | |
8 // See http://www.boost.org for updates, documentation, and revision history. | |
9 // | |
10 // This file is a modified file from Boost.Pool | |
11 | |
12 ////////////////////////////////////////////////////////////////////////////// | |
13 // | |
14 // (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost | |
15 // Software License, Version 1.0. (See accompanying file | |
16 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
17 // | |
18 // See http://www.boost.org/libs/container for documentation. | |
19 // | |
20 ////////////////////////////////////////////////////////////////////////////// | |
21 | |
22 #ifndef BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP | |
23 #define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP | |
24 | |
25 #ifndef BOOST_CONFIG_HPP | |
26 # include <boost/config.hpp> | |
27 #endif | |
28 | |
29 #if defined(BOOST_HAS_PRAGMA_ONCE) | |
30 # pragma once | |
31 #endif | |
32 | |
33 #include <boost/container/detail/config_begin.hpp> | |
34 #include <boost/container/detail/workaround.hpp> | |
35 | |
36 // | |
37 // The following helper classes are placeholders for a generic "singleton" | |
38 // class. The classes below support usage of singletons, including use in | |
39 // program startup/shutdown code, AS LONG AS there is only one thread | |
40 // running before main() begins, and only one thread running after main() | |
41 // exits. | |
42 // | |
43 // This class is also limited in that it can only provide singleton usage for | |
44 // classes with default constructors. | |
45 // | |
46 | |
47 // The design of this class is somewhat twisted, but can be followed by the | |
48 // calling inheritance. Let us assume that there is some user code that | |
49 // calls "singleton_default<T>::instance()". The following (convoluted) | |
50 // sequence ensures that the same function will be called before main(): | |
51 // instance() contains a call to create_object.do_nothing() | |
52 // Thus, object_creator is implicitly instantiated, and create_object | |
53 // must exist. | |
54 // Since create_object is a static member, its constructor must be | |
55 // called before main(). | |
56 // The constructor contains a call to instance(), thus ensuring that | |
57 // instance() will be called before main(). | |
58 // The first time instance() is called (i.e., before main()) is the | |
59 // latest point in program execution where the object of type T | |
60 // can be created. | |
61 // Thus, any call to instance() will auto-magically result in a call to | |
62 // instance() before main(), unless already present. | |
63 // Furthermore, since the instance() function contains the object, instead | |
64 // of the singleton_default class containing a static instance of the | |
65 // object, that object is guaranteed to be constructed (at the latest) in | |
66 // the first call to instance(). This permits calls to instance() from | |
67 // static code, even if that code is called before the file-scope objects | |
68 // in this file have been initialized. | |
69 | |
70 namespace boost { | |
71 namespace container { | |
72 namespace container_detail { | |
73 | |
74 // T must be: no-throw default constructible and no-throw destructible | |
75 template <typename T> | |
76 struct singleton_default | |
77 { | |
78 private: | |
79 struct object_creator | |
80 { | |
81 // This constructor does nothing more than ensure that instance() | |
82 // is called before main() begins, thus creating the static | |
83 // T object before multithreading race issues can come up. | |
84 object_creator() { singleton_default<T>::instance(); } | |
85 inline void do_nothing() const { } | |
86 }; | |
87 static object_creator create_object; | |
88 | |
89 singleton_default(); | |
90 | |
91 public: | |
92 typedef T object_type; | |
93 | |
94 // If, at any point (in user code), singleton_default<T>::instance() | |
95 // is called, then the following function is instantiated. | |
96 static object_type & instance() | |
97 { | |
98 // This is the object that we return a reference to. | |
99 // It is guaranteed to be created before main() begins because of | |
100 // the next line. | |
101 static object_type obj; | |
102 | |
103 // The following line does nothing else than force the instantiation | |
104 // of singleton_default<T>::create_object, whose constructor is | |
105 // called before main() begins. | |
106 create_object.do_nothing(); | |
107 | |
108 return obj; | |
109 } | |
110 }; | |
111 template <typename T> | |
112 typename singleton_default<T>::object_creator | |
113 singleton_default<T>::create_object; | |
114 | |
115 } // namespace container_detail | |
116 } // namespace container | |
117 } // namespace boost | |
118 | |
119 #include <boost/container/detail/config_end.hpp> | |
120 | |
121 #endif //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP |