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