OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 Optional_h | 5 #ifndef Optional_h |
6 #define Optional_h | 6 #define Optional_h |
7 | 7 |
8 #include "wtf/Alignment.h" | 8 #include "base/optional.h" |
9 #include "wtf/Allocator.h" | 9 #include "wtf/TypeTraits.h" |
10 #include "wtf/Assertions.h" | |
11 #include "wtf/Noncopyable.h" | |
12 #include "wtf/StdLibExtras.h" | |
13 | |
14 #include <new> | |
15 #include <utility> | |
16 | 10 |
17 namespace WTF { | 11 namespace WTF { |
18 | 12 |
19 // This is a lightweight template similar to std::experimental::optional. | 13 // See base/optional.h for documentation. |
20 // It currently does not support assignment, swapping, comparison, etc. | 14 template <typename T> |
21 // | 15 class Optional : public base::Optional<T> { |
22 // Use this instead of OwnPtr for cases where you only want to conditionally | 16 static_assert(!IsGarbageCollectedType<T>::value, "Garbage collected types sh ould not be stack-allocated."); |
jbroman
2016/04/20 21:13:24
FYI, doing things this way will cause most of the
danakj
2016/04/20 21:33:22
Yes! That's what I really want, thank you for the
| |
23 // construct a "scope" object. | 17 }; |
24 // | |
25 // Example: | |
26 // Optional<DrawingRecorder> recorder; | |
27 // if (shouldDraw) | |
28 // recorder.emplace(constructor, args, here); | |
29 // // recorder destroyed at end of scope | |
30 // | |
31 // It can be used in WTF::Vector. | |
32 // | |
33 // Note in particular that unlike a pointer, though, dereferencing a const | |
34 // optional yields a const reference. | |
35 | 18 |
36 template <typename T> | 19 constexpr base::nullopt_t nullopt = base::nullopt; |
37 class Optional final { | 20 constexpr base::in_place_t in_place = base::in_place; |
38 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | |
39 WTF_MAKE_NONCOPYABLE(Optional); | |
40 public: | |
41 Optional() : m_ptr(nullptr) { } | |
42 ~Optional() | |
43 { | |
44 if (m_ptr) | |
45 m_ptr->~T(); | |
46 } | |
47 | |
48 typedef T* Optional::*UnspecifiedBoolType; | |
49 operator UnspecifiedBoolType() const { return m_ptr ? &Optional::m_ptr : nul lptr; } | |
50 | |
51 T& operator*() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; } | |
52 const T& operator*() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; } | |
53 T* operator->() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; } | |
54 const T* operator->() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); retur n m_ptr; } | |
55 T* get() { return m_ptr; } | |
56 const T* get() const { return m_ptr; } | |
57 | |
58 template <typename... Args> | |
59 void emplace(Args&&... args) | |
60 { | |
61 RELEASE_ASSERT(!m_ptr); | |
62 m_ptr = reinterpret_cast_ptr<T*>(&m_storage.buffer); | |
63 new (m_ptr) T(std::forward<Args>(args)...); | |
64 } | |
65 | |
66 private: | |
67 T* m_ptr; | |
68 AlignedBuffer<sizeof(T), WTF_ALIGN_OF(T)> m_storage; | |
69 }; | |
70 | 21 |
71 } // namespace WTF | 22 } // namespace WTF |
72 | 23 |
73 using WTF::Optional; | 24 using WTF::Optional; |
74 | 25 |
75 #endif // Optional_h | 26 #endif // Optional_h |
OLD | NEW |