]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/Initialize.h
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / common / Initialize.h
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