Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions docs/design_rationale.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,11 @@ zero changes to the library or to the box types.
template <beman::monadics::box Box>
requires beman::monadics::box<typename beman::monadics::get_box_traits<Box>::value_type>
constexpr auto flatten(Box&& box) {
using Traits = beman::monadics::get_box_traits<Box>;
using InnerBox = typename Traits::value_type;
using ITraits = beman::monadics::get_box_traits<InnerBox>;
using Traits = beman::monadics::get_box_traits<Box>;
using InnerBox = typename Traits::value_type;

if (!Traits::has_value(box))
return ITraits::make_error(Traits::error(std::forward<Box>(box)));
return beman::monadics::propagate_error<InnerBox>(std::forward<Box>(box));
return Traits::value(std::forward<Box>(box));
}
```
Expand Down
4 changes: 2 additions & 2 deletions include/beman/monadics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ target_sources(
detail/meta_rebind.hpp
detail/or_else.hpp
detail/pipe_adaptor.hpp
detail/rebox_value.hpp
detail/rebox_error.hpp
detail/propagate_value.hpp
detail/propagate_error.hpp
detail/same_box.hpp
detail/same_unqualified_as.hpp
detail/transform.hpp
Expand Down
4 changes: 2 additions & 2 deletions include/beman/monadics/detail/and_then.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <beman/monadics/detail/get_box_traits.hpp>
#include <beman/monadics/detail/invoke_with_value.hpp>
#include <beman/monadics/detail/pipe_adaptor.hpp>
#include <beman/monadics/detail/rebox_error.hpp>
#include <beman/monadics/detail/propagate_error.hpp>
#include <beman/monadics/detail/same_box.hpp>

#include <utility>
Expand Down Expand Up @@ -37,7 +37,7 @@ class and_then_t {

using NewBox = decltype(invoke_with_value(std::forward<Op>(op).callable(key), std::forward<Box>(box)));

return rebox_error<NewBox>(std::forward<Box>(box));
return propagate_error<NewBox>(std::forward<Box>(box));
}
};

Expand Down
19 changes: 13 additions & 6 deletions include/beman/monadics/detail/invoke_with_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@
namespace beman::monadics::detail {

template<typename Fn, typename Box, typename Traits = get_box_traits<Box>>
[[nodiscard]] constexpr decltype(auto) invoke_with_error(Fn&& fn, Box&& box) noexcept
requires requires {
{ Traits::error(std::forward<Box>(box)) };
{ std::forward<Fn>(fn)(Traits::error(std::forward<Box>(box))) };
} || requires { requires std::invocable<Fn>; }
concept invocable_with_error = requires {
requires has_error_channel<Box>;
{ std::declval<Fn>()(Traits::error(std::declval<Box>())) };
} || requires {
requires !has_error_channel<Box>;
requires std::invocable<Fn>;
};

template<typename Fn, box Box>
[[nodiscard]] constexpr decltype(auto) invoke_with_error(Fn&& fn, Box&& box)
requires invocable_with_error<decltype(fn), decltype(box)>
{
if constexpr (requires { Traits::error(std::forward<Box>(box)); }) {
using Traits = get_box_traits<Box>;
if constexpr (has_error_channel<Box>) {
return std::forward<Fn>(fn)(Traits::error(std::forward<Box>(box)));
} else {
return std::forward<Fn>(fn)();
Expand Down
20 changes: 12 additions & 8 deletions include/beman/monadics/detail/invoke_with_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@

namespace beman::monadics::detail {

template<typename Fn, box Box, typename Traits = get_box_traits<Box>>
[[nodiscard]] constexpr decltype(auto) invoke_with_value(Fn&& fn, Box&& box) noexcept
requires requires {
{ Traits::value(std::forward<Box>(box)) } -> std::same_as<void>;
{ fn() };
} || requires {
{ fn(Traits::value(std::forward<Box>(box))) };
}
template<typename Fn, typename Box, typename Traits = get_box_traits<Box>>
concept invocable_with_value = requires {
requires std::is_void_v<typename Traits::value_type>;
requires std::invocable<Fn>;
} || requires {
{ std::declval<Fn>()(Traits::value(std::declval<Box>())) };
};

template<typename Fn, box Box>
[[nodiscard]] constexpr decltype(auto) invoke_with_value(Fn&& fn, Box&& box)
requires invocable_with_value<decltype(fn), decltype(box)>
{
using Traits = get_box_traits<Box>;
if constexpr (std::is_void_v<typename Traits::value_type> && std::invocable<Fn>) {
// should just invoke Traits::value(box);
return std::forward<Fn>(fn)();
Expand Down
4 changes: 2 additions & 2 deletions include/beman/monadics/detail/or_else.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <beman/monadics/detail/get_box_traits.hpp>
#include <beman/monadics/detail/invoke_with_error.hpp>
#include <beman/monadics/detail/pipe_adaptor.hpp>
#include <beman/monadics/detail/rebox_value.hpp>
#include <beman/monadics/detail/propagate_value.hpp>
#include <beman/monadics/detail/same_box.hpp>

#include <utility>
Expand Down Expand Up @@ -36,7 +36,7 @@ class or_else_t {
return invoke_with_error(std::forward<Op>(op).callable(key), std::forward<Box>(box));
}

return rebox_value<NewBox>(std::forward<Box>(box));
return propagate_value<NewBox>(std::forward<Box>(box));
}
};

Expand Down
37 changes: 37 additions & 0 deletions include/beman/monadics/detail/propagate_error.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef BEMAN_MONADICS_DETAIL_PROPAGATE_ERROR_HPP
#define BEMAN_MONADICS_DETAIL_PROPAGATE_ERROR_HPP

#include <beman/monadics/detail/get_box_traits.hpp>
#include <beman/monadics/detail/same_box.hpp>

#include <utility>

namespace beman::monadics::detail {

template<typename NewBox, typename Box>
concept propagatable_error = same_box<NewBox, Box> && (requires {
requires has_error_channel<Box>;
{ get_box_traits<NewBox>::make_error(get_box_traits<Box>::error(std::declval<Box>())) };
} || requires {
requires !has_error_channel<Box>;
{ get_box_traits<NewBox>::make_error(get_box_traits<Box>::error()) };
});

template<typename NewBox, typename Box>
requires propagatable_error<NewBox, Box>
[[nodiscard]] constexpr decltype(auto) propagate_error(Box&& box) {
using BoxTraits = get_box_traits<Box>;
using NewBoxTraits = get_box_traits<NewBox>;

if constexpr (has_error_channel<Box>) {
return NewBoxTraits::make_error(BoxTraits::error(std::forward<Box>(box)));
} else {
return NewBoxTraits::make_error(BoxTraits::error());
}
}

} // namespace beman::monadics::detail

#endif // BEMAN_MONADICS_DETAIL_PROPAGATE_ERROR_HPP
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef BEMAN_MONADICS_DETAIL_REBOX_VALUE_HPP
#define BEMAN_MONADICS_DETAIL_REBOX_VALUE_HPP
#ifndef BEMAN_MONADICS_DETAIL_PROPAGATE_VALUE_HPP
#define BEMAN_MONADICS_DETAIL_PROPAGATE_VALUE_HPP

#include <beman/monadics/detail/get_box_traits.hpp>
#include <beman/monadics/detail/same_box.hpp>
Expand All @@ -12,8 +12,16 @@
namespace beman::monadics::detail {

template<typename NewBox, typename Box>
requires same_box<NewBox, Box>
[[nodiscard]] constexpr decltype(auto) rebox_value(Box&& box) noexcept {
concept propagatable_value = same_box<NewBox, Box> && (requires {
requires std::is_void_v<typename get_box_traits<NewBox>::value_type>;
{ get_box_traits<NewBox>::make() };
} || requires {
{ get_box_traits<NewBox>::make(get_box_traits<Box>::value(std::declval<Box>())) };
});

template<typename NewBox, typename Box>
requires propagatable_value<NewBox, Box>
[[nodiscard]] constexpr decltype(auto) propagate_value(Box&& box) {
using BoxTraits = get_box_traits<Box>;
using NewBoxTraits = get_box_traits<NewBox>;

Expand All @@ -26,4 +34,4 @@ template<typename NewBox, typename Box>

} // namespace beman::monadics::detail

#endif // BEMAN_MONADICS_DETAIL_REBOX_VALUE_HPP
#endif // BEMAN_MONADICS_DETAIL_PROPAGATE_VALUE_HPP
28 changes: 0 additions & 28 deletions include/beman/monadics/detail/rebox_error.hpp

This file was deleted.

4 changes: 2 additions & 2 deletions include/beman/monadics/detail/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <beman/monadics/detail/get_box_traits.hpp>
#include <beman/monadics/detail/invoke_with_value.hpp>
#include <beman/monadics/detail/pipe_adaptor.hpp>
#include <beman/monadics/detail/rebox_error.hpp>
#include <beman/monadics/detail/propagate_error.hpp>
#include <beman/monadics/detail/same_box.hpp>

#include <type_traits>
Expand Down Expand Up @@ -42,7 +42,7 @@ class transform_t {
}
}

return rebox_error<NewBox>(std::forward<Box>(box));
return propagate_error<NewBox>(std::forward<Box>(box));
}
};

Expand Down
2 changes: 1 addition & 1 deletion include/beman/monadics/detail/transform_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class transform_error_t {
std::forward<Box>(box)));
}

return rebox_value<NewBox>(std::forward<Box>(box));
return propagate_value<NewBox>(std::forward<Box>(box));

// gcc11/12 internal crash with pipe_adaptor_t
// return std::forward<Box>(box) | or_else([f = std::forward<Op>(op).callable(key)](auto&& e) {
Expand Down
8 changes: 8 additions & 0 deletions include/beman/monadics/monadics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
#include <beman/monadics/detail/access_key.hpp>
#include <beman/monadics/detail/and_then.hpp>
#include <beman/monadics/detail/get_box_traits.hpp>
#include <beman/monadics/detail/invoke_with_error.hpp>
#include <beman/monadics/detail/invoke_with_value.hpp>
#include <beman/monadics/detail/or_else.hpp>
#include <beman/monadics/detail/pipe_adaptor.hpp>
#include <beman/monadics/detail/propagate_error.hpp>
#include <beman/monadics/detail/propagate_value.hpp>
#include <beman/monadics/detail/transform.hpp>
#include <beman/monadics/detail/transform_error.hpp>

Expand All @@ -20,9 +24,13 @@ using detail::box;
using detail::box_traits;
using detail::get_box_traits;
using detail::has_error_channel;
using detail::invoke_with_error;
using detail::invoke_with_value;
using detail::or_else;
using detail::or_elseable;
using detail::pipe_adaptor;
using detail::propagate_error;
using detail::propagate_value;
using detail::transform;
using detail::transform_error;
using detail::transform_errorable;
Expand Down
4 changes: 2 additions & 2 deletions tests/beman/monadics/detail/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ set(tests
meta_rebind_error
meta_rebind
pipe_adaptor
rebox_error
rebox_value
propagate_error
propagate_value
same_box
)

Expand Down
Loading
Loading