1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2024 Google LLC. 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_HPB_PTR_H__ 9 #define GOOGLE_PROTOBUF_HPB_PTR_H__ 10 11 #include <memory> 12 #include <type_traits> 13 14 class upb_Message; 15 class upb_Arena; 16 17 namespace hpb { 18 19 template <typename T> 20 using Proxy = std::conditional_t<std::is_const<T>::value, 21 typename std::remove_const_t<T>::CProxy, 22 typename T::Proxy>; 23 24 // Provides convenient access to Proxy and CProxy message types. 25 // 26 // Using rebinding and handling of const, Ptr<Message> and Ptr<const Message> 27 // allows copying const with T* const and avoids using non-copyable Proxy types 28 // directly. 29 template <typename T> 30 class Ptr final { 31 public: 32 Ptr() = delete; 33 34 // Implicit conversions Ptr(T * m)35 Ptr(T* m) : p_(m) {} // NOLINT Ptr(const Proxy<T> * p)36 Ptr(const Proxy<T>* p) : p_(*p) {} // NOLINT Ptr(Proxy<T> p)37 Ptr(Proxy<T> p) : p_(p) {} // NOLINT 38 Ptr(const Ptr& m) = default; 39 40 Ptr& operator=(Ptr v) & { 41 Proxy<T>::Rebind(p_, v.p_); 42 return *this; 43 } 44 45 Proxy<T> operator*() const { return p_; } 46 Proxy<T>* operator->() const { 47 return const_cast<Proxy<T>*>(std::addressof(p_)); 48 } 49 50 #ifdef __clang__ 51 #pragma clang diagnostic push 52 #pragma clang diagnostic ignored "-Wclass-conversion" 53 #endif 54 template <typename U = T, std::enable_if_t<!std::is_const<U>::value, int> = 0> 55 operator Ptr<const T>() const { 56 Proxy<const T> p(p_); 57 return Ptr<const T>(&p); 58 } 59 #ifdef __clang__ 60 #pragma clang diagnostic pop 61 #endif 62 63 private: Ptr(upb_Message * msg,upb_Arena * arena)64 Ptr(upb_Message* msg, upb_Arena* arena) : p_(msg, arena) {} // NOLINT 65 66 friend class Ptr<const T>; 67 friend typename T::Access; 68 69 Proxy<T> p_; 70 }; 71 72 // Suppress -Wctad-maybe-unsupported with our manual deduction guide 73 template <typename T> 74 Ptr(T* m) -> Ptr<T>; 75 76 } // namespace hpb 77 78 #endif // GOOGLE_PROTOBUF_HPB_PTR_H__ 79