summaryrefslogtreecommitdiff
path: root/src/optional.hh
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-06-27 19:34:26 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-06-27 21:10:09 +0100
commitdf3bf7445dfd27389551e138333c1b42e92b30ab (patch)
treea45f531659dc443e151df53c54df6ec610e98652 /src/optional.hh
parent7aa78d726a54fa57a8dc5ed973ab0b30eeba6bf3 (diff)
Replace boost::optional with our own implementation
Diffstat (limited to 'src/optional.hh')
-rw-r--r--src/optional.hh77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/optional.hh b/src/optional.hh
new file mode 100644
index 00000000..61dc9618
--- /dev/null
+++ b/src/optional.hh
@@ -0,0 +1,77 @@
+#ifndef optional_hh_INCLUDED
+#define optional_hh_INCLUDED
+
+namespace Kakoune
+{
+
+template<typename T>
+struct Optional
+{
+public:
+ constexpr Optional() : m_valid(false) {}
+ Optional(const T& other) : m_valid(true) { new (&m_value) T(other); }
+ Optional(T&& other) : m_valid(true) { new (&m_value) T(std::move(other)); }
+
+ Optional(const Optional& other)
+ : m_valid(other.m_valid)
+ {
+ if (m_valid)
+ new (&m_value) T(other.m_value);
+ }
+
+ Optional(Optional&& other)
+ : m_valid(other.m_valid)
+ {
+ if (m_valid)
+ new (&m_value) T(std::move(other.m_value));
+ }
+
+ Optional& operator=(const Optional& other)
+ {
+ if (m_valid)
+ m_value.~T();
+ if ((m_valid = other.m_valid))
+ new (&m_value) T(other.m_value);
+ return *this;
+ }
+
+ Optional& operator=(Optional&& other)
+ {
+ if (m_valid)
+ m_value.~T();
+ if ((m_valid = other.m_valid))
+ new (&m_value) T(std::move(other.m_value));
+ return *this;
+ }
+
+ ~Optional()
+ {
+ if (m_valid)
+ m_value.~T();
+ }
+
+ constexpr explicit operator bool() const noexcept { return m_valid; }
+
+ T& operator*()
+ {
+ kak_assert(m_valid);
+ return m_value;
+ }
+ const T& operator*() const { return *const_cast<Optional&>(*this); }
+
+ T* operator->()
+ {
+ kak_assert(m_valid);
+ return &m_value;
+ }
+ const T* operator->() const { return const_cast<Optional&>(*this).operator->(); }
+
+private:
+ bool m_valid;
+ union { T m_value; };
+};
+
+}
+
+#endif // optional_hh_INCLUDED
+