Skip to content

Commit 714d800

Browse files
authored
Merge pull request #149 from steve-downey/or-else-constraint
Put constraints on `or_else` overloads
2 parents 78c9abb + 5ab7c24 commit 714d800

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

include/beman/optional/optional.hpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,8 @@ class optional {
727727
* @return optional
728728
*/
729729
template <class F>
730-
constexpr optional or_else(F&& f) const&;
730+
constexpr optional or_else(F&& f) const&
731+
requires (std::invocable<F> && std::copy_constructible<T>);
731732

732733
/**
733734
* @brief Returns an optional containing the contained value if it has one, or
@@ -738,7 +739,8 @@ class optional {
738739
* @return auto
739740
*/
740741
template <class F>
741-
constexpr optional or_else(F&& f) &&;
742+
constexpr optional or_else(F&& f) &&
743+
requires (std::invocable<F> && std::move_constructible<T>);
742744

743745
// \ref{optional.mod}, modifiers
744746
/**
@@ -1231,7 +1233,9 @@ constexpr auto optional<T>::transform(F&& f) const&& {
12311233
*/
12321234
template <class T>
12331235
template <class F>
1234-
constexpr optional<T> optional<T>::or_else(F&& f) const& {
1236+
constexpr optional<T> optional<T>::or_else(F&& f) const&
1237+
requires (std::invocable<F> && std::copy_constructible<T>)
1238+
{
12351239
static_assert(std::is_same_v<std::remove_cvref_t<std::invoke_result_t<F>>, optional>);
12361240
if (has_value())
12371241
return value_;
@@ -1250,7 +1254,9 @@ constexpr optional<T> optional<T>::or_else(F&& f) const& {
12501254
*/
12511255
template <class T>
12521256
template <class F>
1253-
constexpr optional<T> optional<T>::or_else(F&& f) && {
1257+
constexpr optional<T> optional<T>::or_else(F&& f) &&
1258+
requires (std::invocable<F> && std::move_constructible<T>)
1259+
{
12541260
static_assert(std::is_same_v<std::remove_cvref_t<std::invoke_result_t<F>>, optional>);
12551261
if (has_value())
12561262
return std::move(value_);
@@ -1870,7 +1876,8 @@ class optional<T&> {
18701876
* return an optional type.
18711877
*/
18721878
template <class F>
1873-
constexpr optional or_else(F&& f) const;
1879+
constexpr optional or_else(F&& f) const
1880+
requires (std::invocable<F>);
18741881

18751882
// \ref{optional.mod}, modifiers
18761883
/**
@@ -2078,7 +2085,10 @@ constexpr optional<std::invoke_result_t<F, T&>> optional<T&>::transform(F&& f) c
20782085
*/
20792086
template <class T>
20802087
template <class F>
2081-
constexpr optional<T&> optional<T&>::or_else(F&& f) const {
2088+
constexpr optional<T&> optional<T&>::or_else(F&& f) const
2089+
2090+
requires (std::invocable<F>)
2091+
{
20822092
using U = std::invoke_result_t<F>;
20832093
static_assert(std::is_same_v<std::remove_cvref_t<U>, optional>, "Result must be an optional");
20842094
if (has_value()) {

0 commit comments

Comments
 (0)