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.