• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <new>
9 
10 #include "mojo/public/cpp/environment/logging.h"
11 #include "mojo/public/cpp/system/macros.h"
12 
13 namespace mojo {
14 namespace internal {
15 
16 template <typename Struct>
17 class StructHelper {
18  public:
19   template <typename Ptr>
Initialize(Ptr * ptr)20   static void Initialize(Ptr* ptr) { ptr->Initialize(); }
21 };
22 
23 }  // namespace internal
24 
25 template <typename Struct>
26 class StructPtr {
27   MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(StructPtr, RValue);
28  public:
29   typedef typename Struct::Data_ Data_;
30 
StructPtr()31   StructPtr() : ptr_(NULL) {}
~StructPtr()32   ~StructPtr() {
33     delete ptr_;
34   }
35 
StructPtr(RValue other)36   StructPtr(RValue other) : ptr_(NULL) { Take(other.object); }
37   StructPtr& operator=(RValue other) {
38     Take(other.object);
39     return *this;
40   }
41 
42   template <typename U>
To()43   U To() const {
44     return TypeConverter<U, StructPtr>::Convert(*this);
45   }
46 
reset()47   void reset() {
48     if (ptr_) {
49       delete ptr_;
50       ptr_ = NULL;
51     }
52   }
53 
is_null()54   bool is_null() const { return ptr_ == NULL; }
55 
56   Struct& operator*() const {
57     MOJO_DCHECK(ptr_);
58     return *ptr_;
59   }
60   Struct* operator->() const {
61     MOJO_DCHECK(ptr_);
62     return ptr_;
63   }
get()64   Struct* get() const { return ptr_; }
65 
Swap(StructPtr * other)66   void Swap(StructPtr* other) {
67     std::swap(ptr_, other->ptr_);
68   }
69 
70  private:
71   typedef Struct* StructPtr::*Testable;
72 
73  public:
Testable()74   operator Testable() const { return ptr_ ? &StructPtr::ptr_ : 0; }
75 
76  private:
77   friend class internal::StructHelper<Struct>;
Initialize()78   void Initialize() {
79     MOJO_DCHECK(!ptr_);
80     ptr_ = new Struct();
81   }
82 
Take(StructPtr * other)83   void Take(StructPtr* other) {
84     reset();
85     Swap(other);
86   }
87 
88   Struct* ptr_;
89 };
90 
91 // Designed to be used when Struct is small and copyable.
92 template <typename Struct>
93 class InlinedStructPtr {
94   MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InlinedStructPtr, RValue);
95  public:
96   typedef typename Struct::Data_ Data_;
97 
InlinedStructPtr()98   InlinedStructPtr() : is_null_(true) {}
~InlinedStructPtr()99   ~InlinedStructPtr() {}
100 
InlinedStructPtr(RValue other)101   InlinedStructPtr(RValue other) : is_null_(true) { Take(other.object); }
102   InlinedStructPtr& operator=(RValue other) {
103     Take(other.object);
104     return *this;
105   }
106 
107   template <typename U>
To()108   U To() const {
109     return TypeConverter<U, InlinedStructPtr>::Convert(*this);
110   }
111 
reset()112   void reset() {
113     is_null_ = true;
114     value_.~Struct();
115     new (&value_) Struct();
116   }
117 
is_null()118   bool is_null() const { return is_null_; }
119 
120   Struct& operator*() const {
121     MOJO_DCHECK(!is_null_);
122     return value_;
123   }
124   Struct* operator->() const {
125     MOJO_DCHECK(!is_null_);
126     return &value_;
127   }
get()128   Struct* get() const { return &value_; }
129 
Swap(InlinedStructPtr * other)130   void Swap(InlinedStructPtr* other) {
131     std::swap(value_, other->value_);
132     std::swap(is_null_, other->is_null_);
133   }
134 
135  private:
136   typedef Struct InlinedStructPtr::*Testable;
137 
138  public:
Testable()139   operator Testable() const { return is_null_ ? 0 : &InlinedStructPtr::value_; }
140 
141  private:
142   friend class internal::StructHelper<Struct>;
Initialize()143   void Initialize() { is_null_ = false; }
144 
Take(InlinedStructPtr * other)145   void Take(InlinedStructPtr* other) {
146     reset();
147     Swap(other);
148   }
149 
150   mutable Struct value_;
151   bool is_null_;
152 };
153 
154 }  // namespace mojo
155 
156 #endif  // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_
157