a4e55e758f440cc6288cfe4968a142ff8030ffac
[platform/framework/web/crosswalk.git] / src / mojo / public / cpp / bindings / struct_ptr.h
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>
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
32   StructPtr() : ptr_(NULL) {}
33   ~StructPtr() {
34     delete ptr_;
35   }
36
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>
44   U To() const {
45     return TypeConverter<StructPtr, U>::ConvertTo(*this);
46   }
47
48   void reset() {
49     if (ptr_) {
50       delete ptr_;
51       ptr_ = NULL;
52     }
53   }
54
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   }
65   Struct* get() const { return ptr_; }
66
67   void Swap(StructPtr* other) {
68     std::swap(ptr_, other->ptr_);
69   }
70
71  private:
72   typedef Struct* StructPtr::*Testable;
73
74  public:
75   operator Testable() const { return ptr_ ? &StructPtr::ptr_ : 0; }
76
77  private:
78   friend class internal::StructHelper<Struct>;
79   void Initialize() { assert(!ptr_); ptr_ = new Struct(); }
80
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
96   InlinedStructPtr() : is_null_(true) {}
97   ~InlinedStructPtr() {}
98
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>
106   U To() const {
107     return TypeConverter<InlinedStructPtr, U>::ConvertTo(*this);
108   }
109
110   void reset() {
111     is_null_ = true;
112     value_.~Struct();
113     new (&value_) Struct();
114   }
115
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   }
126   Struct* get() const { return &value_; }
127
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:
137   operator Testable() const { return is_null_ ? 0 : &InlinedStructPtr::value_; }
138
139  private:
140   friend class internal::StructHelper<Struct>;
141   void Initialize() { is_null_ = false; }
142
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_