xref: /aosp_15_r20/external/protobuf/src/google/protobuf/explicitly_constructed.h (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #ifndef GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
32 #define GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
33 
34 #include <stdint.h>
35 
36 #include <utility>
37 
38 #include <google/protobuf/stubs/logging.h>
39 #include <google/protobuf/stubs/common.h>
40 
41 // clang-format off
42 #include <google/protobuf/port_def.inc>
43 // clang-format on
44 
45 namespace google {
46 namespace protobuf {
47 namespace internal {
48 
49 // Wraps a variable whose constructor and destructor are explicitly
50 // called. It is particularly useful for a global variable, without its
51 // constructor and destructor run on start and end of the program lifetime.
52 // This circumvents the initial construction order fiasco, while keeping
53 // the address of the empty string a compile time constant.
54 //
55 // Pay special attention to the initialization state of the object.
56 // 1. The object is "uninitialized" to begin with.
57 // 2. Call Construct() or DefaultConstruct() only if the object is
58 //    uninitialized. After the call, the object becomes "initialized".
59 // 3. Call get() and get_mutable() only if the object is initialized.
60 // 4. Call Destruct() only if the object is initialized.
61 //    After the call, the object becomes uninitialized.
62 template <typename T, size_t min_align = 1>
63 class ExplicitlyConstructed {
64  public:
DefaultConstruct()65   void DefaultConstruct() { new (&union_) T(); }
66 
67   template <typename... Args>
Construct(Args &&...args)68   void Construct(Args&&... args) {
69     new (&union_) T(std::forward<Args>(args)...);
70   }
71 
Destruct()72   void Destruct() { get_mutable()->~T(); }
73 
get()74   constexpr const T& get() const { return reinterpret_cast<const T&>(union_); }
get_mutable()75   T* get_mutable() { return reinterpret_cast<T*>(&union_); }
76 
77  private:
78   union AlignedUnion {
79     alignas(min_align > alignof(T) ? min_align
80                                    : alignof(T)) char space[sizeof(T)];
81     int64_t align_to_int64;
82     void* align_to_ptr;
83   } union_;
84 };
85 
86 // ArenaStringPtr compatible explicitly constructed string type.
87 // This empty string type is aligned with a minimum alignment of 8 bytes
88 // which is the minimum requirement of ArenaStringPtr
89 using ExplicitlyConstructedArenaString = ExplicitlyConstructed<std::string, 8>;
90 
91 }  // namespace internal
92 }  // namespace protobuf
93 }  // namespace google
94 
95 #include <google/protobuf/port_undef.inc>
96 
97 #endif  // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
98