Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef Optional_h | |
| 6 #define Optional_h | |
| 7 | |
| 8 #include "wtf/Alignment.h" | |
| 9 #include "wtf/Assertions.h" | |
| 10 #include "wtf/Noncopyable.h" | |
| 11 #include "wtf/StdLibExtras.h" | |
| 12 #include "wtf/Utility.h" | |
| 13 | |
| 14 namespace WTF { | |
| 15 | |
| 16 // This is a lightweight template similar to std::experimental::optional. | |
| 17 // It currently does not support assignment, swapping, comparison, etc. | |
| 18 // | |
| 19 // Use this instead of OwnPtr for cases where you only want to conditionally | |
| 20 // construct a "scope" object. | |
| 21 // | |
| 22 // Example: | |
| 23 // Optional<DrawingRecorder> recorder; | |
| 24 // if (shouldDraw) | |
| 25 // recorder.emplace(constructor, args, here); | |
| 26 // // recorder destroyed at end of scope | |
| 27 // | |
| 28 // Note in particular that unlike a pointer, though, dereferencing a const | |
| 29 // optional yields a const reference. | |
| 30 | |
| 31 template <typename T> | |
| 32 class Optional { | |
| 33 WTF_MAKE_NONCOPYABLE(Optional); | |
| 34 public: | |
| 35 Optional() : m_engaged(false) { } | |
| 36 ~Optional() | |
| 37 { | |
| 38 if (m_engaged) | |
| 39 storage()->~T(); | |
| 40 } | |
| 41 | |
| 42 typedef bool Optional::*UnspecifiedBoolType; | |
| 43 operator UnspecifiedBoolType() const { return m_engaged ? &Optional::m_engag ed : nullptr; } | |
| 44 | |
| 45 T& operator*() { ASSERT(m_engaged); return *storage(); } | |
|
esprehn
2015/06/02 02:00:23
These should all be ASSERT_WITH_SECURITY_IMPLICATI
jbroman
2015/06/02 14:13:48
Right you are. https://codereview.chromium.org/115
| |
| 46 const T& operator*() const { ASSERT(m_engaged); return *storage(); } | |
| 47 T* operator->() { ASSERT(m_engaged); return storage(); } | |
| 48 const T* operator->() const { ASSERT(m_engaged); return storage(); } | |
| 49 | |
| 50 template <typename... Args> | |
| 51 void emplace(Args&&... args) | |
| 52 { | |
| 53 ASSERT(!m_engaged); | |
| 54 new (storage()) T(forward<Args>(args)...); | |
| 55 m_engaged = true; | |
| 56 } | |
| 57 | |
| 58 private: | |
| 59 T* storage() { return reinterpret_cast_ptr<T*>(&m_storage.buffer); } | |
| 60 const T* storage() const { return reinterpret_cast_ptr<const T*>(&m_storage. buffer); } | |
| 61 | |
| 62 bool m_engaged; | |
| 63 AlignedBuffer<sizeof(T), WTF_ALIGN_OF(T)> m_storage; | |
| 64 }; | |
| 65 | |
| 66 } // namespace WTF | |
| 67 | |
| 68 using WTF::Optional; | |
| 69 | |
| 70 #endif // Optional_h | |
| OLD | NEW |