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 |