• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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