| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ | |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ | |
| 7 | |
| 8 #include <cstddef> | |
| 9 #include <memory> | |
| 10 #include <new> | |
| 11 | |
| 12 #include "mojo/public/cpp/bindings/type_converter.h" | |
| 13 #include "mojo/public/cpp/environment/logging.h" | |
| 14 #include "mojo/public/cpp/system/macros.h" | |
| 15 | |
| 16 namespace mojo { | |
| 17 namespace internal { | |
| 18 | |
| 19 template <typename Struct> | |
| 20 class StructHelper { | |
| 21 public: | |
| 22 template <typename Ptr> | |
| 23 static void Initialize(Ptr* ptr) { | |
| 24 ptr->Initialize(); | |
| 25 } | |
| 26 }; | |
| 27 | |
| 28 } // namespace internal | |
| 29 | |
| 30 // Smart pointer wrapping a mojom structure or union, with move-only semantics. | |
| 31 template <typename Struct> | |
| 32 class StructPtr { | |
| 33 public: | |
| 34 StructPtr() {} | |
| 35 StructPtr(std::nullptr_t) {} | |
| 36 | |
| 37 ~StructPtr() {} | |
| 38 | |
| 39 StructPtr& operator=(std::nullptr_t) { | |
| 40 reset(); | |
| 41 return *this; | |
| 42 } | |
| 43 | |
| 44 StructPtr(StructPtr&& other) { Take(&other); } | |
| 45 StructPtr& operator=(StructPtr&& other) { | |
| 46 Take(&other); | |
| 47 return *this; | |
| 48 } | |
| 49 | |
| 50 template <typename U> | |
| 51 U To() const { | |
| 52 return TypeConverter<U, StructPtr>::Convert(*this); | |
| 53 } | |
| 54 | |
| 55 void reset() { ptr_.reset(); } | |
| 56 | |
| 57 // Tests as true if non-null, false if null. | |
| 58 explicit operator bool() const { return !!ptr_; } | |
| 59 | |
| 60 bool is_null() const { return !ptr_; } | |
| 61 | |
| 62 Struct& operator*() const { | |
| 63 MOJO_DCHECK(ptr_); | |
| 64 return *ptr_; | |
| 65 } | |
| 66 Struct* operator->() const { | |
| 67 MOJO_DCHECK(ptr_); | |
| 68 return ptr_.get(); | |
| 69 } | |
| 70 Struct* get() const { return ptr_.get(); } | |
| 71 | |
| 72 void Swap(StructPtr* other) { std::swap(ptr_, other->ptr_); } | |
| 73 | |
| 74 // Please note that calling this method will fail compilation if the value | |
| 75 // type |Struct| doesn't have a Clone() method defined (which usually means | |
| 76 // that it contains Mojo handles). | |
| 77 StructPtr Clone() const { return is_null() ? StructPtr() : ptr_->Clone(); } | |
| 78 | |
| 79 bool Equals(const StructPtr& other) const { | |
| 80 if (is_null() || other.is_null()) | |
| 81 return is_null() && other.is_null(); | |
| 82 return ptr_->Equals(*other.ptr_); | |
| 83 } | |
| 84 | |
| 85 private: | |
| 86 friend class internal::StructHelper<Struct>; | |
| 87 void Initialize() { | |
| 88 MOJO_DCHECK(!ptr_); | |
| 89 ptr_.reset(new Struct()); | |
| 90 } | |
| 91 | |
| 92 void Take(StructPtr* other) { | |
| 93 reset(); | |
| 94 Swap(other); | |
| 95 } | |
| 96 | |
| 97 std::unique_ptr<Struct> ptr_; | |
| 98 | |
| 99 MOJO_MOVE_ONLY_TYPE(StructPtr); | |
| 100 }; | |
| 101 | |
| 102 // Designed to be used when Struct is small and copyable. Unions are always | |
| 103 // InlinedStructPtr in practice. | |
| 104 template <typename Struct> | |
| 105 class InlinedStructPtr { | |
| 106 public: | |
| 107 InlinedStructPtr() : is_null_(true) {} | |
| 108 InlinedStructPtr(std::nullptr_t) : is_null_(true) {} | |
| 109 | |
| 110 ~InlinedStructPtr() {} | |
| 111 | |
| 112 InlinedStructPtr& operator=(std::nullptr_t) { | |
| 113 reset(); | |
| 114 return *this; | |
| 115 } | |
| 116 | |
| 117 InlinedStructPtr(InlinedStructPtr&& other) : is_null_(true) { Take(&other); } | |
| 118 InlinedStructPtr& operator=(InlinedStructPtr&& other) { | |
| 119 Take(&other); | |
| 120 return *this; | |
| 121 } | |
| 122 | |
| 123 template <typename U> | |
| 124 U To() const { | |
| 125 return TypeConverter<U, InlinedStructPtr>::Convert(*this); | |
| 126 } | |
| 127 | |
| 128 void reset() { | |
| 129 is_null_ = true; | |
| 130 value_. ~Struct(); | |
| 131 new (&value_) Struct(); | |
| 132 } | |
| 133 | |
| 134 // Tests as true if non-null, false if null. | |
| 135 explicit operator bool() const { return !is_null_; } | |
| 136 | |
| 137 bool is_null() const { return is_null_; } | |
| 138 | |
| 139 Struct& operator*() const { | |
| 140 MOJO_DCHECK(!is_null_); | |
| 141 return value_; | |
| 142 } | |
| 143 Struct* operator->() const { | |
| 144 MOJO_DCHECK(!is_null_); | |
| 145 return &value_; | |
| 146 } | |
| 147 Struct* get() const { return is_null() ? nullptr : &value_; } | |
| 148 | |
| 149 void Swap(InlinedStructPtr* other) { | |
| 150 std::swap(value_, other->value_); | |
| 151 std::swap(is_null_, other->is_null_); | |
| 152 } | |
| 153 | |
| 154 InlinedStructPtr Clone() const { | |
| 155 return is_null() ? InlinedStructPtr() : value_.Clone(); | |
| 156 } | |
| 157 bool Equals(const InlinedStructPtr& other) const { | |
| 158 if (is_null() || other.is_null()) | |
| 159 return is_null() && other.is_null(); | |
| 160 return value_.Equals(other.value_); | |
| 161 } | |
| 162 | |
| 163 private: | |
| 164 friend class internal::StructHelper<Struct>; | |
| 165 void Initialize() { is_null_ = false; } | |
| 166 | |
| 167 void Take(InlinedStructPtr* other) { | |
| 168 reset(); | |
| 169 Swap(other); | |
| 170 } | |
| 171 | |
| 172 mutable Struct value_; | |
| 173 bool is_null_; | |
| 174 | |
| 175 MOJO_MOVE_ONLY_TYPE(InlinedStructPtr); | |
| 176 }; | |
| 177 | |
| 178 } // namespace mojo | |
| 179 | |
| 180 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ | |
| OLD | NEW |