From ed27d58e95c4382b90869b477a06d1b02cb9d2f5 Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Sat, 21 Oct 2017 19:41:18 +0100 Subject: [PATCH] Docs --- docs/index.md | 149 +++++++++++++++++++++++++++++++++++++++++++------- optional.hpp | 120 ++++++++++++++++++++++++++++++++-------- 2 files changed, 226 insertions(+), 43 deletions(-) diff --git a/docs/index.md b/docs/index.md index 3aed36f..aab5c61 100644 --- a/docs/index.md +++ b/docs/index.md @@ -149,20 +149,58 @@ Represents an empty optional class optional { public: - template <class F> constexpr auto and_then(F &&f); - template <class F> constexpr auto and_then(F &&f) const; + template <class F> + constexpr auto and_then(F &&f) &; + template <class F> + constexpr auto and_then(F &&f) &&; + template <class F> + constexpr auto and_then(F &&f) const &; + template <class F> + constexpr auto and_then(F &&f) const &&; - template <class F> auto map(F &&f); - template <class F> auto map(F &&f) const; + template <class F> auto map(F &&f) &; + template <class F> auto map(F &&f) &&; + template <class F> auto map(F &&f) const &; + template <class F> auto map(F &&f) const &&; - template <class F> optional<T> or_else (F &&f); - template <class F> optional<T> or_else (F &&f) const; + template <class F> optional<T> or_else (F &&f) &; + template <class F> optional<T> or_else (F &&f) &&; + template <class F> optional<T> or_else (F &&f) const &; - template <class F, class U> U map_or(F &&f, U &&u); - template <class F, class U> U map_or(F &&f, U &&u) const; + template <class F, class U> + U map_or(F&& f, U&& u) &; + template <class F, class U> + U map_or(F&& f, U&& u) &&; + template <class F, class U> + U map_or(F&& f, U&& u) const &; + template <class F, class U> + U map_or(F&& f, U&& u) const &&; - template <class F, class U> U map_or_else(F &&f, U &&u); - template <class F, class U> U map_or_else(F &&f, U &&u) const; + template <class F, class U> + U map_or_else(F&& f, U&& u) &; + template <class F, class U> + U map_or_else(F&& f, U&& u) &&; + template <class F, class U> + U map_or_else(F&& f, U&& u) const &; + template <class F, class U> + U map_or_else(F&& f, U&& u) const &&; + + template <class U> + constexpr optional<U> conjunction(U&& u) const; + + constexpr optional disjunction(const optional& rhs) &; + constexpr optional disjunction(const optional& rhs) const &; + constexpr optional disjunction(const optional& rhs) &&; + constexpr optional disjunction(const optional& rhs) const &&; + constexpr optional disjunction(optional&& rhs) &; + constexpr optional disjunction(optional&& rhs) const &; + constexpr optional disjunction(optional&& rhs) &&; + constexpr optional disjunction(optional&& rhs) const &&; + + optional take() &; + optional take() const &; + optional take() &&; + optional take() const &&; using value_type = T; @@ -228,9 +266,17 @@ An optional object is an object that contains the storage for another object and ### Function template `tl::optional::and_then` -
(1)  template <class F> constexpr auto and_then(F &&f);
+
(1)  template <class F>
+     constexpr auto and_then(F &&f) &;
 
-(2)  template <class F> constexpr auto and_then(F &&f) const;
+(2) template <class F> + constexpr auto and_then(F &&f) &&; + +(3) template <class F> + constexpr auto and_then(F &&f) const &; + +(4) template <class F> + constexpr auto and_then(F &&f) const &&;
Carries out some operation which returns an optional on the stored object if there is one. @@ -240,9 +286,13 @@ Carries out some operation which returns an optional on the stored object if the ### Function template `tl::optional::map` -
(1)  template <class F> auto map(F &&f);
+
(1)  template <class F> auto map(F &&f) &;
 
-(2)  template <class F> auto map(F &&f) const;
+(2) template <class F> auto map(F &&f) &&; + +(3) template <class F> auto map(F &&f) const &; + +(4) template <class F> auto map(F &&f) const &&;
Carries out some operation on the stored object if there is one. @@ -250,9 +300,11 @@ Carries out some operation on the stored object if there is one. ### Function template `tl::optional::or_else` -
(1)  template <class F> optional<T> or_else (F &&f);
+
(1)  template <class F> optional<T> or_else (F &&f) &;
 
-(2)  template <class F> optional<T> or_else (F &&f) const;
+(2) template <class F> optional<T> or_else (F &&f) &&; + +(3) template <class F> optional<T> or_else (F &&f) const &;
Calls `f` if the optional is empty @@ -262,9 +314,17 @@ Calls `f` if the optional is empty ### Function template `tl::optional::map_or` -
(1)  template <class F, class U> U map_or(F &&f, U &&u);
+
(1)  template <class F, class U>
+     U map_or(F&& f, U&& u) &;
 
-(2)  template <class F, class U> U map_or(F &&f, U &&u) const;
+(2) template <class F, class U> + U map_or(F&& f, U&& u) &&; + +(3) template <class F, class U> + U map_or(F&& f, U&& u) const &; + +(4) template <class F, class U> + U map_or(F&& f, U&& u) const &&;
Maps the stored value with `f` if there is one, otherwise returns `u` @@ -272,14 +332,61 @@ If there is a value stored, then `f` is called with `**this` and the value is re ### Function template `tl::optional::map_or_else` -
(1)  template <class F, class U> U map_or_else(F &&f, U &&u);
+
(1)  template <class F, class U>
+     U map_or_else(F&& f, U&& u) &;
 
-(2)  template <class F, class U> U map_or_else(F &&f, U &&u) const;
+(2) template <class F, class U> + U map_or_else(F&& f, U&& u) &&; + +(3) template <class F, class U> + U map_or_else(F&& f, U&& u) const &; + +(4) template <class F, class U> + U map_or_else(F&& f, U&& u) const &&;
Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result. If there is a value stored, then `f` is called with `**this` and the value is returned. Otherwise `std::forward(u)()` is returned. +### Function template `tl::optional::conjunction` + +
template <class U>
+constexpr optional<U> conjunction(U&& u) const;
+ +*Returns*: `u` if `*this` has a value, otherwise an empty optional. + +### Function `tl::optional::disjunction` + +
(1)  constexpr optional disjunction(const optional& rhs) &;
+
+(2)  constexpr optional disjunction(const optional& rhs) const &;
+
+(3)  constexpr optional disjunction(const optional& rhs) &&;
+
+(4)  constexpr optional disjunction(const optional& rhs) const &&;
+
+(5)  constexpr optional disjunction(optional&& rhs) &;
+
+(6)  constexpr optional disjunction(optional&& rhs) const &;
+
+(7)  constexpr optional disjunction(optional&& rhs) &&;
+
+(8)  constexpr optional disjunction(optional&& rhs) const &&;
+ +*Returns*: `rhs` if `*this` is empty, otherwise the current value. + +### Function `tl::optional::take` + +
(1)  optional take() &;
+
+(2)  optional take() const &;
+
+(3)  optional take() &&;
+
+(4)  optional take() const &&;
+ +Takes the value out of the optional, leaving it empty + ### Default constructor `tl::optional::optional`
(1)  constexpr optional() noexcept = default;
@@ -335,7 +442,7 @@ Converting move constructor.
 
 
~optional() = default;
-Destructor. +Destroys the stored value if there is one. ### Assignment operator `tl::optional::operator=` diff --git a/optional.hpp b/optional.hpp index 623e10d..8636761 100644 --- a/optional.hpp +++ b/optional.hpp @@ -361,7 +361,7 @@ public: /// \requires `std::invoke(std::forward(f), value())` returns a `std::optional` for some `U`. /// \returns Let `U` be the result of `std::invoke(std::forward(f), value())`. Returns a `std::optional`. The return value is empty if `*this` is empty, otherwise the return value of `std::invoke(std::forward(f), value())` is returned. /// \group and_then - /// \synopsis template constexpr auto and_then(F &&f); + /// \synopsis template \nconstexpr auto and_then(F &&f) &; template TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F &&f) & { using result = detail::invoke_result_t; @@ -372,7 +372,8 @@ public: : result(nullopt); } - /// \exclude + /// \group and_then + /// \synopsis template \nconstexpr auto and_then(F &&f) &&; template TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F &&f) && { using result = detail::invoke_result_t; @@ -384,7 +385,7 @@ public: } /// \group and_then - /// \synopsis template constexpr auto and_then(F &&f) const; + /// \synopsis template \nconstexpr auto and_then(F &&f) const &; template constexpr detail::invoke_result_t and_then(F &&f) const & { using result = detail::invoke_result_t; @@ -395,7 +396,8 @@ public: : result(nullopt); } - /// \exclude + /// \group and_then + /// \synopsis template \nconstexpr auto and_then(F &&f) const &&; template constexpr detail::invoke_result_t and_then(F &&f) const && { using result = detail::invoke_result_t; @@ -409,7 +411,7 @@ public: /// \brief Carries out some operation on the stored object if there is one. /// \returns Let `U` be the result of `std::invoke(std::forward(f), value())`. Returns a `std::optional`. The return value is empty if `*this` is empty, otherwise an `optional` is constructed from the return value of `std::invoke(std::forward(f), value())` and is returned. /// \group map - /// \synopsis template auto map(F &&f); + /// \synopsis template auto map(F &&f) &; template * = nullptr, detail::disable_if_ret_void * = nullptr> detail::get_map_return map(F &&f) & @@ -452,7 +454,8 @@ public: return monostate{}; } - /// \exclude + /// \group map + /// \synopsis template auto map(F &&f) &&; template * = nullptr, detail::disable_if_ret_void * = nullptr> detail::get_map_return map(F &&f) && { @@ -494,7 +497,7 @@ public: } /// \group map - /// \synopsis template auto map(F &&f) const; + /// \synopsis template auto map(F &&f) const &; template * = nullptr, detail::disable_if_ret_void * = nullptr> constexpr detail::get_map_return map(F &&f) const & { @@ -536,7 +539,8 @@ public: return monostate{}; } - /// \exclude + /// \group map + /// \synopsis template auto map(F &&f) const &&; template * = nullptr, detail::disable_if_ret_void * = nullptr> constexpr detail::get_map_return map(F &&f) const && { @@ -581,7 +585,7 @@ public: /// \requires `std::invoke_result_t` must be void or convertible to `optional`. /// \effects If `*this` has a value, returns `*this`. Otherwise, if `f` returns `void`, calls `std::forward(f)` and returns `std::nullopt`. Otherwise, returns `std::forward(f)()`. /// \group or_else - /// \synopsis template optional or_else (F &&f); + /// \synopsis template optional or_else (F &&f) &; template * = nullptr> optional TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) & { if (has_value()) @@ -597,7 +601,8 @@ public: return has_value() ? *this : std::forward(f)(); } - /// \exclude + /// \group or_else + /// \synopsis template optional or_else (F &&f) &&; template * = nullptr> optional or_else(F &&f) && { if (has_value()) @@ -613,7 +618,8 @@ public: return has_value() ? std::move(*this) : std::forward(f)(); } - /// \exclude + /// \group or_else + /// \synopsis template optional or_else (F &&f) const &; template * = nullptr> optional or_else(F &&f) const & { if (has_value()) @@ -623,8 +629,7 @@ public: return nullopt; } - /// \group or_else - /// \synopsis template optional or_else (F &&f) const; + /// \exclude template * = nullptr> optional TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) const & { return has_value() ? *this : std::forward(f)(); @@ -651,26 +656,24 @@ public: /// \details If there is a value stored, then `f` is called with `**this` and the value is returned. /// Otherwise `u` is returned. /// \group map_or - /// \synopsis template U map_or(F &&f, U &&u); template U map_or(F &&f, U &&u) & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u); } - /// \exclude + /// \group map_or template U map_or(F &&f, U &&u) && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u); } /// \group map_or - /// \synopsis template U map_or(F &&f, U &&u) const; template U map_or(F &&f, U &&u) const & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u); } - /// \exclude + /// \group map_or template U map_or(F &&f, U &&u) const && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u); @@ -679,32 +682,105 @@ public: /// \brief Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result. /// \details If there is a value stored, then `f` is called with `**this` and the value is returned. /// Otherwise `std::forward(u)()` is returned. - /// \synopsis template U map_or_else(F &&f, U &&u); /// \group map_or_else template U map_or_else(F &&f, U &&u) & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u)(); } - /// \exclude + /// \group map_or_else template U map_or_else(F &&f, U &&u) && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u)(); } /// \group map_or_else - /// \synopsis template U map_or_else(F &&f, U &&u) const; template U map_or_else(F &&f, U &&u) const & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u)(); } - /// \exclude + /// \group map_or_else template U map_or_else(F &&f, U &&u) const && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u)(); } + /// \returns `u` if `*this` has a value, otherwise an empty optional. + template constexpr optional conjunction (U &&u) const { + return has_value() ? u : nullopt; + } + + /// \returns `rhs` if `*this` is empty, otherwise the current value. + /// \group disjunction + constexpr optional disjunction (const optional &rhs) & { + return has_value() ? *this : rhs; + } + + /// \group disjunction + constexpr optional disjunction (const optional &rhs) const & { + return has_value() ? *this : rhs; + } + + /// \group disjunction + constexpr optional disjunction (const optional &rhs) && { + return has_value() ? std::move(*this) : rhs; + } + + /// \group disjunction + constexpr optional disjunction (const optional &rhs) const && { + return has_value() ? std::move(*this) : rhs; + } + + /// \group disjunction + constexpr optional disjunction (optional &&rhs) & { + return has_value() ? *this : std::move(rhs); + } + + /// \group disjunction + constexpr optional disjunction (optional &&rhs) const & { + return has_value() ? *this : std::move(rhs); + } + + /// \group disjunction + constexpr optional disjunction (optional &&rhs) && { + return has_value() ? std::move(*this) : std::move(rhs); + } + + /// \group disjunction + constexpr optional disjunction (optional &&rhs) const && { + return has_value() ? std::move(*this) : std::move(rhs); + } + + /// Takes the value out of the optional, leaving it empty + /// \group take + optional take() & { + optional ret = *this; + reset(); + return ret; + } + + /// \group take + optional take() const & { + optional ret = *this; + reset(); + return ret; + } + + /// \group take + optional take() && { + optional ret = std::move(*this); + reset(); + return ret; + } + + /// \group take + optional take() const && { + optional ret = std::move(*this); + reset(); + return ret; + } + using value_type = T; /// Constructs an optional that does not contain a value. @@ -813,7 +889,7 @@ public: new (std::addressof(this->m_value)) T(std::move(*rhs)); } - /// Destructor. + /// Destroys the stored value if there is one. ~optional() = default; /// Assignment to empty.