OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef DataPersistent_h | 5 #ifndef DataPersistent_h |
6 #define DataPersistent_h | 6 #define DataPersistent_h |
7 | 7 |
8 #include "platform/heap/Handle.h" | 8 #include "platform/heap/Handle.h" |
9 #include "wtf/Allocator.h" | 9 #include "wtf/Allocator.h" |
10 #include "wtf/OwnPtr.h" | 10 #include "wtf/PtrUtil.h" |
| 11 #include <memory> |
11 | 12 |
12 namespace blink { | 13 namespace blink { |
13 | 14 |
14 // DataPersistent<T> provides the copy-on-modify behavior of DataRef<>, | 15 // DataPersistent<T> provides the copy-on-modify behavior of DataRef<>, |
15 // but for Persistent<> heap references. | 16 // but for Persistent<> heap references. |
16 // | 17 // |
17 // That is, the DataPersistent<T> copy assignment, |a = b;|, makes |a| | 18 // That is, the DataPersistent<T> copy assignment, |a = b;|, makes |a| |
18 // share a reference to the T object that |b| holds until |a| is mutated | 19 // share a reference to the T object that |b| holds until |a| is mutated |
19 // and access() on it is called. Or, dually, if |b| is mutated after the | 20 // and access() on it is called. Or, dually, if |b| is mutated after the |
20 // assignment that mutation isn't observable to |a| but will be performed | 21 // assignment that mutation isn't observable to |a| but will be performed |
21 // on a copy of the underlying T object. | 22 // on a copy of the underlying T object. |
22 // | 23 // |
23 // DataPersistent<T> does assume that no one keeps non-DataPersistent<> shared | 24 // DataPersistent<T> does assume that no one keeps non-DataPersistent<> shared |
24 // references to the underlying T object that it manages, and is mutating the | 25 // references to the underlying T object that it manages, and is mutating the |
25 // object via those. | 26 // object via those. |
26 template <typename T> | 27 template <typename T> |
27 class DataPersistent { | 28 class DataPersistent { |
28 USING_FAST_MALLOC(DataPersistent); | 29 USING_FAST_MALLOC(DataPersistent); |
29 public: | 30 public: |
30 DataPersistent() | 31 DataPersistent() |
31 : m_ownCopy(false) | 32 : m_ownCopy(false) |
32 { | 33 { |
33 } | 34 } |
34 | 35 |
35 DataPersistent(const DataPersistent& other) | 36 DataPersistent(const DataPersistent& other) |
36 : m_ownCopy(false) | 37 : m_ownCopy(false) |
37 { | 38 { |
38 if (other.m_data) | 39 if (other.m_data) |
39 m_data = adoptPtr(new Persistent<T>(other.m_data->get())); | 40 m_data = wrapUnique(new Persistent<T>(other.m_data->get())); |
40 | 41 |
41 // Invalidated, subsequent mutations will happen on a new copy. | 42 // Invalidated, subsequent mutations will happen on a new copy. |
42 // | 43 // |
43 // (Clearing |m_ownCopy| will not be observable over T, hence | 44 // (Clearing |m_ownCopy| will not be observable over T, hence |
44 // the const_cast<> is considered acceptable here.) | 45 // the const_cast<> is considered acceptable here.) |
45 const_cast<DataPersistent&>(other).m_ownCopy = false; | 46 const_cast<DataPersistent&>(other).m_ownCopy = false; |
46 } | 47 } |
47 | 48 |
48 const T* get() const { return m_data ? m_data->get() : nullptr; } | 49 const T* get() const { return m_data ? m_data->get() : nullptr; } |
49 | 50 |
50 const T& operator*() const { return m_data ? *get() : nullptr; } | 51 const T& operator*() const { return m_data ? *get() : nullptr; } |
51 const T* operator->() const { return get(); } | 52 const T* operator->() const { return get(); } |
52 | 53 |
53 T* access() | 54 T* access() |
54 { | 55 { |
55 if (m_data && !m_ownCopy) { | 56 if (m_data && !m_ownCopy) { |
56 *m_data = (*m_data)->copy(); | 57 *m_data = (*m_data)->copy(); |
57 m_ownCopy = true; | 58 m_ownCopy = true; |
58 } | 59 } |
59 return m_data ? m_data->get() : nullptr; | 60 return m_data ? m_data->get() : nullptr; |
60 } | 61 } |
61 | 62 |
62 void init() | 63 void init() |
63 { | 64 { |
64 ASSERT(!m_data); | 65 ASSERT(!m_data); |
65 m_data = adoptPtr(new Persistent<T>(T::create())); | 66 m_data = wrapUnique(new Persistent<T>(T::create())); |
66 m_ownCopy = true; | 67 m_ownCopy = true; |
67 } | 68 } |
68 | 69 |
69 bool operator==(const DataPersistent<T>& o) const | 70 bool operator==(const DataPersistent<T>& o) const |
70 { | 71 { |
71 ASSERT(m_data); | 72 ASSERT(m_data); |
72 ASSERT(o.m_data); | 73 ASSERT(o.m_data); |
73 return m_data->get() == o.m_data->get() || *m_data->get() == *o.m_data->
get(); | 74 return m_data->get() == o.m_data->get() || *m_data->get() == *o.m_data->
get(); |
74 } | 75 } |
75 | 76 |
76 bool operator!=(const DataPersistent<T>& o) const | 77 bool operator!=(const DataPersistent<T>& o) const |
77 { | 78 { |
78 ASSERT(m_data); | 79 ASSERT(m_data); |
79 ASSERT(o.m_data); | 80 ASSERT(o.m_data); |
80 return m_data->get() != o.m_data->get() && *m_data->get() != *o.m_data->
get(); | 81 return m_data->get() != o.m_data->get() && *m_data->get() != *o.m_data->
get(); |
81 } | 82 } |
82 | 83 |
83 void operator=(std::nullptr_t) { m_data.clear(); } | 84 void operator=(std::nullptr_t) { m_data.clear(); } |
84 private: | 85 private: |
85 // Reduce size of DataPersistent<> by delaying creation of Persistent<>. | 86 // Reduce size of DataPersistent<> by delaying creation of Persistent<>. |
86 OwnPtr<Persistent<T>> m_data; | 87 std::unique_ptr<Persistent<T>> m_data; |
87 unsigned m_ownCopy:1; | 88 unsigned m_ownCopy:1; |
88 }; | 89 }; |
89 | 90 |
90 } // namespace blink | 91 } // namespace blink |
91 | 92 |
92 #endif // DataPersistent_h | 93 #endif // DataPersistent_h |
OLD | NEW |