]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | /* | |
3 | * Ceph - scalable distributed file system | |
4 | * | |
5 | * Copyright (C) 2014 UnitedStack <haomai@unitedstack.com> | |
6 | * | |
7 | * Author: Haomai Wang <haomaiwang@gmail.com> | |
8 | * | |
9 | * This is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License version 2.1, as published by the Free Software | |
12 | * Foundation. See file COPYING. | |
13 | * | |
14 | */ | |
15 | /* Copyright (c) 2011 Stanford University | |
16 | * | |
17 | * Permission to use, copy, modify, and distribute this software for any | |
18 | * purpose with or without fee is hereby granted, provided that the above | |
19 | * copyright notice and this permission notice appear in all copies. | |
20 | * | |
21 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES | |
22 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
23 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR | |
24 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
25 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
26 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
27 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
28 | */ | |
29 | ||
30 | #ifndef CEPH_INITIALIZE_H | |
31 | #define CEPH_INITIALIZE_H | |
32 | ||
33 | /** | |
34 | * This class is used to manage once-only initialization that should occur | |
35 | * before main() is invoked, such as the creation of static variables. It | |
36 | * also provides a mechanism for handling dependencies (where one class | |
37 | * needs to perform its once-only initialization before another). | |
38 | * | |
39 | * The simplest way to use an Initialize object is to define a static | |
40 | * initialization method for a class, say Foo::init(). Then, declare | |
41 | * a static Initialize object in the class: | |
42 | * "static Initialize initializer(Foo::init);". | |
43 | * The result is that Foo::init will be invoked when the object is | |
44 | * constructed (before main() is invoked). Foo::init can create static | |
45 | * objects and perform any other once-only initialization needed by the | |
46 | * class. Furthermore, if some other class needs to ensure that Foo has | |
47 | * been initialized (e.g. as part of its own initialization) it can invoke | |
48 | * Foo::init directly (Foo::init should contain an internal guard so that | |
49 | * it only performs its functions once, even if invoked several times). | |
50 | * | |
51 | * There is also a second form of constructor for Initialize that causes a | |
52 | * new object to be dynamically allocated and assigned to a pointer, instead | |
53 | * of invoking a function. This form allows for the creation of static objects | |
54 | * that are never destructed (thereby avoiding issues with the order of | |
55 | * destruction). | |
56 | */ | |
57 | class Initialize { | |
58 | public: | |
59 | /** | |
60 | * This form of constructor causes its function argument to be invoked | |
61 | * when the object is constructed. When used with a static Initialize | |
62 | * object, this will cause \p func to run before main() runs, so that | |
63 | * \p func can perform once-only initialization. | |
64 | * | |
65 | * \param func | |
66 | * This function is invoked with no arguments when the object is | |
67 | * constructed. Typically the function will create static | |
68 | * objects and/or invoke other initialization functions. The | |
69 | * function should normally contain an internal guard so that it | |
70 | * only performs its initialization the first time it is invoked. | |
71 | */ | |
72 | explicit Initialize(void (*func)()) { | |
73 | (*func)(); | |
74 | } | |
75 | ||
76 | /** | |
77 | * This form of constructor causes a new object of a particular class | |
78 | * to be constructed with a no-argument constructor and assigned to a | |
79 | * given pointer. This form is typically used with a static Initialize | |
80 | * object: the result is that the object will be created and assigned | |
81 | * to the pointer before main() runs. | |
82 | * | |
83 | * \param p | |
84 | * Pointer to an object of any type. If the pointer is NULL then | |
85 | * it is replaced with a pointer to a newly allocated object of | |
86 | * the given type. | |
87 | */ | |
88 | template<typename T> | |
89 | explicit Initialize(T*& p) { | |
90 | if (p == NULL) { | |
91 | p = new T; | |
92 | } | |
93 | } | |
94 | }; | |
95 | ||
96 | #endif // CEPH_INITIALIZE_H |