From df3bf7445dfd27389551e138333c1b42e92b30ab Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 27 Jun 2014 19:34:26 +0100 Subject: [PATCH] Replace boost::optional with our own implementation --- src/context.hh | 7 ++--- src/optional.hh | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ src/selectors.cc | 11 +++---- 3 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 src/optional.hh diff --git a/src/context.hh b/src/context.hh index 57780070..a02f11fd 100644 --- a/src/context.hh +++ b/src/context.hh @@ -2,8 +2,7 @@ #define context_hh_INCLUDED #include "selection.hh" - -#include +#include "optional.hh" namespace Kakoune { @@ -34,7 +33,7 @@ public: Context& operator=(const Context&) = delete; Buffer& buffer() const; - bool has_buffer() const { return m_selections; } + bool has_buffer() const { return (bool)m_selections; } Window& window() const; bool has_window() const { return (bool)m_window; } @@ -88,7 +87,7 @@ private: safe_ptr m_client; friend class Client; - boost::optional m_selections; + Optional m_selections; String m_name; 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 +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(*this); } + + T* operator->() + { + kak_assert(m_valid); + return &m_value; + } + const T* operator->() const { return const_cast(*this).operator->(); } + +private: + bool m_valid; + union { T m_value; }; +}; + +} + +#endif // optional_hh_INCLUDED + diff --git a/src/selectors.cc b/src/selectors.cc index 838f1de1..b2b08073 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -1,11 +1,10 @@ #include "selectors.hh" +#include "optional.hh" #include "string.hh" #include -#include - namespace Kakoune { @@ -74,9 +73,7 @@ Selection select_matching(const Buffer& buffer, const Selection& selection) return selection; } -// c++14 will add std::optional, so we use boost::optional until then -using boost::optional; -static optional find_surrounding(const Buffer& buffer, +static Optional find_surrounding(const Buffer& buffer, ByteCoord coord, CodepointPair matching, ObjectFlags flags, int init_level) @@ -103,7 +100,7 @@ static optional find_surrounding(const Buffer& buffer, --first; } if (level != 0 or *first != matching.first) - return optional{}; + return Optional{}; } Utf8Iterator last = pos; @@ -124,7 +121,7 @@ static optional find_surrounding(const Buffer& buffer, ++last; } if (level != 0 or last == buffer.end()) - return optional{}; + return Optional{}; } if (flags & ObjectFlags::Inner)