Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / wtf / Optional.h
blob264b45ed616936fddd1284997a7c3ff21520e711
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.
5 #ifndef Optional_h
6 #define Optional_h
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"
14 namespace WTF {
16 // This is a lightweight template similar to std::experimental::optional.
17 // It currently does not support assignment, swapping, comparison, etc.
19 // Use this instead of OwnPtr for cases where you only want to conditionally
20 // construct a "scope" object.
22 // Example:
23 // Optional<DrawingRecorder> recorder;
24 // if (shouldDraw)
25 // recorder.emplace(constructor, args, here);
26 // // recorder destroyed at end of scope
28 // Note in particular that unlike a pointer, though, dereferencing a const
29 // optional yields a const reference.
31 template <typename T>
32 class Optional {
33 WTF_MAKE_NONCOPYABLE(Optional);
34 public:
35 Optional() : m_ptr(nullptr) { }
36 ~Optional()
38 if (m_ptr)
39 m_ptr->~T();
42 typedef T* Optional::*UnspecifiedBoolType;
43 operator UnspecifiedBoolType() const { return m_ptr ? &Optional::m_ptr : nullptr; }
45 T& operator*() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; }
46 const T& operator*() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; }
47 T* operator->() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; }
48 const T* operator->() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; }
50 template <typename... Args>
51 void emplace(Args&&... args)
53 RELEASE_ASSERT(!m_ptr);
54 m_ptr = reinterpret_cast_ptr<T*>(&m_storage.buffer);
55 new (m_ptr) T(forward<Args>(args)...);
58 private:
59 T* m_ptr;
60 AlignedBuffer<sizeof(T), WTF_ALIGN_OF(T)> m_storage;
63 } // namespace WTF
65 using WTF::Optional;
67 #endif // Optional_h