1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef GOOGLE_PROTOBUF_RAW_PTR_H__ 9 #define GOOGLE_PROTOBUF_RAW_PTR_H__ 10 11 #include <algorithm> 12 13 #include "absl/base/optimization.h" 14 15 // Must be included last. 16 #include "google/protobuf/port_def.inc" 17 18 namespace google { 19 namespace protobuf { 20 namespace internal { 21 22 PROTOBUF_EXPORT ABSL_CACHELINE_ALIGNED extern const char 23 kZeroBuffer[std::max(ABSL_CACHELINE_SIZE, 64)]; 24 25 // This class is trivially copyable/trivially destructible and constexpr 26 // constructible. The class allows for storing a raw pointer to a non-trivial 27 // object in a constexpr context. 28 template <typename T> 29 class RawPtr { 30 public: RawPtr()31 constexpr RawPtr() : RawPtr(kZeroBuffer) { 32 static_assert(sizeof(T) <= sizeof(kZeroBuffer), ""); 33 static_assert(alignof(T) <= ABSL_CACHELINE_SIZE, ""); 34 } RawPtr(const void * p)35 explicit constexpr RawPtr(const void* p) : p_(const_cast<void*>(p)) {} 36 IsDefault()37 bool IsDefault() const { return p_ == kZeroBuffer; } DeleteIfNotDefault()38 void DeleteIfNotDefault() { 39 if (!IsDefault()) delete Get(); 40 } ClearIfNotDefault()41 void ClearIfNotDefault() { 42 if (!IsDefault()) Get()->Clear(); 43 } 44 Set(const void * p)45 void Set(const void* p) { p_ = const_cast<void*>(p); } Get()46 T* Get() const { return reinterpret_cast<T*>(p_); } 47 T* operator->() const { return Get(); } 48 T& operator*() const { return *Get(); } 49 50 private: 51 void* p_; 52 }; 53 DefaultRawPtr()54constexpr void* DefaultRawPtr() { 55 return const_cast<void*>(static_cast<const void*>(kZeroBuffer)); 56 } 57 58 } // namespace internal 59 } // namespace protobuf 60 } // namespace google 61 62 #include "google/protobuf/port_undef.inc" 63 64 #endif // GOOGLE_PROTOBUF_RAW_PTR_H__ 65