summaryrefslogtreecommitdiff
path: root/src/optional.hh
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-04-01 22:09:32 +1100
committerMaxime Coste <mawww@kakoune.org>2019-04-01 22:09:32 +1100
commitb8cf457e82a18233b30c696577ea57dd85aee6b8 (patch)
tree518587ec9d80c36de6eca3d7b3f56731f1f3461f /src/optional.hh
parent0b758909bef17c3e9d2279b638001d323db31b07 (diff)
Add Optional::map and Optional::cast methods
Cool kids call that monadic interface if I understood correctly.
Diffstat (limited to 'src/optional.hh')
-rw-r--r--src/optional.hh20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/optional.hh b/src/optional.hh
index aef1a751..e6ff2b83 100644
--- a/src/optional.hh
+++ b/src/optional.hh
@@ -81,6 +81,26 @@ public:
}
const T* operator->() const { return const_cast<Optional&>(*this).operator->(); }
+ template<typename U> struct DecayOptionalImpl { using Type = U; };
+ template<typename U> struct DecayOptionalImpl<Optional<U>> { using Type = typename DecayOptionalImpl<U>::Type; };
+ template<typename U> using DecayOptional = typename DecayOptionalImpl<U>::Type;
+
+ template<typename F>
+ auto map(F f) -> Optional<DecayOptional<decltype(f(std::declval<T&&>()))>>
+ {
+ if (not m_valid)
+ return {};
+ return {f(m_value)};
+ }
+
+ template<typename U>
+ auto cast() -> Optional<U>
+ {
+ if (not m_valid)
+ return {};
+ return {(U)m_value};
+ }
+
template<typename U>
T value_or(U&& fallback) const { return m_valid ? m_value : T{std::forward<U>(fallback)}; }