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 // WTF::Optional is base::Optional. See base/optional.h for documentation. |
20 // It currently does not support assignment, swapping, comparison, etc. | |
21 // | 14 // |
22 // Use this instead of OwnPtr for cases where you only want to conditionally | 15 // A clang plugin enforces that garbage collected types are not allocated |
23 // construct a "scope" object. | 16 // outside of the heap, similarly we enforce that one doesn't create garbage |
24 // | 17 // collected types nested inside an Optional. |
25 // Example: | 18 template <typename T> |
26 // Optional<DrawingRecorder> recorder; | 19 using Optional = typename std::enable_if<!IsGarbageCollectedType<T>::value, base
::Optional<T>>::type; |
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 | 20 |
36 template <typename T> | 21 constexpr base::nullopt_t nullopt = base::nullopt; |
37 class Optional final { | 22 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 | 23 |
71 } // namespace WTF | 24 } // namespace WTF |
72 | 25 |
73 using WTF::Optional; | 26 using WTF::Optional; |
74 | 27 |
75 #endif // Optional_h | 28 #endif // Optional_h |
OLD | NEW |