| // Protocol Buffers - Google's data interchange format | |
| // Copyright 2008 Google Inc. All rights reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file or at | |
| // https://developers.google.com/open-source/licenses/bsd | |
| #ifndef GOOGLE_PROTOBUF_RAW_PTR_H__ | |
| #define GOOGLE_PROTOBUF_RAW_PTR_H__ | |
| #include <algorithm> | |
| #include "absl/base/optimization.h" | |
| // Must be included last. | |
| #include "google/protobuf/port_def.inc" | |
| namespace google { | |
| namespace protobuf { | |
| namespace internal { | |
| PROTOBUF_EXPORT ABSL_CACHELINE_ALIGNED extern const char | |
| kZeroBuffer[std::max(ABSL_CACHELINE_SIZE, 64)]; | |
| // This class is trivially copyable/trivially destructible and constexpr | |
| // constructible. The class allows for storing a raw pointer to a non-trivial | |
| // object in a constexpr context. | |
| template <typename T> | |
| class RawPtr { | |
| public: | |
| constexpr RawPtr() : RawPtr(kZeroBuffer) { | |
| static_assert(sizeof(T) <= sizeof(kZeroBuffer), ""); | |
| static_assert(alignof(T) <= ABSL_CACHELINE_SIZE, ""); | |
| } | |
| explicit constexpr RawPtr(const void* p) : p_(const_cast<void*>(p)) {} | |
| bool IsDefault() const { return p_ == kZeroBuffer; } | |
| void DeleteIfNotDefault() { | |
| if (!IsDefault()) delete Get(); | |
| } | |
| void ClearIfNotDefault() { | |
| if (!IsDefault()) Get()->Clear(); | |
| } | |
| void Set(const void* p) { p_ = const_cast<void*>(p); } | |
| T* Get() const { return reinterpret_cast<T*>(p_); } | |
| T* operator->() const { return Get(); } | |
| T& operator*() const { return *Get(); } | |
| // For simplicity of codegen, we provide forwarding APIs | |
| operator const T&() const { return *Get(); } // NOLINT | |
| operator T&() { return *Get(); } // NOLINT | |
| auto begin() const { return Get()->begin(); } | |
| auto end() const { return Get()->end(); } | |
| private: | |
| void* p_; | |
| }; | |
| constexpr void* DefaultRawPtr() { | |
| return const_cast<void*>(static_cast<const void*>(kZeroBuffer)); | |
| } | |
| } // namespace internal | |
| } // namespace protobuf | |
| } // namespace google | |
| #include "google/protobuf/port_undef.inc" | |
| #endif // GOOGLE_PROTOBUF_RAW_PTR_H__ |