|
||||
File indexing completed on 2025-01-31 10:12:19
0001 // Protocol Buffers - Google's data interchange format 0002 // Copyright 2008 Google Inc. All rights reserved. 0003 // 0004 // Use of this source code is governed by a BSD-style 0005 // license that can be found in the LICENSE file or at 0006 // https://developers.google.com/open-source/licenses/bsd 0007 0008 #ifndef GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__ 0009 #define GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__ 0010 0011 #include <stdint.h> 0012 0013 #include <string> 0014 #include <utility> 0015 0016 // clang-format off 0017 #include "google/protobuf/port_def.inc" 0018 // clang-format on 0019 0020 namespace google { 0021 namespace protobuf { 0022 namespace internal { 0023 0024 // Wraps a variable whose constructor and destructor are explicitly 0025 // called. It is particularly useful for a global variable, without its 0026 // constructor and destructor run on start and end of the program lifetime. 0027 // This circumvents the initial construction order fiasco, while keeping 0028 // the address of the empty string a compile time constant. 0029 // 0030 // Pay special attention to the initialization state of the object. 0031 // 1. The object is "uninitialized" to begin with. 0032 // 2. Call Construct() or DefaultConstruct() only if the object is 0033 // uninitialized. After the call, the object becomes "initialized". 0034 // 3. Call get() and get_mutable() only if the object is initialized. 0035 // 4. Call Destruct() only if the object is initialized. 0036 // After the call, the object becomes uninitialized. 0037 template <typename T, size_t min_align = 1> 0038 class ExplicitlyConstructed { 0039 public: 0040 void DefaultConstruct() { new (&union_) T(); } 0041 0042 template <typename... Args> 0043 void Construct(Args&&... args) { 0044 new (&union_) T(std::forward<Args>(args)...); 0045 } 0046 0047 void Destruct() { get_mutable()->~T(); } 0048 0049 constexpr const T& get() const { return reinterpret_cast<const T&>(union_); } 0050 T* get_mutable() { return reinterpret_cast<T*>(&union_); } 0051 0052 private: 0053 union AlignedUnion { 0054 alignas(min_align > alignof(T) ? min_align 0055 : alignof(T)) char space[sizeof(T)]; 0056 int64_t align_to_int64; 0057 void* align_to_ptr; 0058 } union_; 0059 }; 0060 0061 // ArenaStringPtr compatible explicitly constructed string type. 0062 // This empty string type is aligned with a minimum alignment of 8 bytes 0063 // which is the minimum requirement of ArenaStringPtr 0064 using ExplicitlyConstructedArenaString = ExplicitlyConstructed<std::string, 8>; 0065 0066 } // namespace internal 0067 } // namespace protobuf 0068 } // namespace google 0069 0070 #include "google/protobuf/port_undef.inc" 0071 0072 #endif // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |