mirror of
https://github.com/BlackMATov/kari.hpp.git
synced 2025-12-13 04:56:49 +07:00
temporary remove variadic curring
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace kari_hpp
|
||||
{
|
||||
template < std::size_t N, typename F, typename... Args >
|
||||
template < typename F, typename... Args >
|
||||
struct curry_t;
|
||||
|
||||
namespace impl
|
||||
@@ -21,8 +21,8 @@ namespace kari_hpp
|
||||
struct is_curried_impl
|
||||
: std::false_type {};
|
||||
|
||||
template < std::size_t N, typename F, typename... Args >
|
||||
struct is_curried_impl<curry_t<N, F, Args...>>
|
||||
template < typename F, typename... Args >
|
||||
struct is_curried_impl<curry_t<F, Args...>>
|
||||
: std::true_type {};
|
||||
}
|
||||
|
||||
@@ -36,48 +36,40 @@ namespace kari_hpp
|
||||
|
||||
namespace kari_hpp::detail
|
||||
{
|
||||
template < std::size_t N, typename F, typename... Args >
|
||||
template < typename F, typename... Args >
|
||||
constexpr auto curry_or_apply(F&& f, std::tuple<Args...>&& args) {
|
||||
if constexpr ( !N && std::is_invocable_v<std::decay_t<F>, Args...> ) {
|
||||
if constexpr ( std::is_invocable_v<std::decay_t<F>, Args...> ) {
|
||||
return std::apply(std::forward<F>(f), std::move(args));
|
||||
} else {
|
||||
return curry_t<N, std::decay_t<F>, Args...>(std::forward<F>(f), std::move(args));
|
||||
return curry_t<std::decay_t<F>, Args...>(std::forward<F>(f), std::move(args));
|
||||
}
|
||||
}
|
||||
|
||||
template < std::size_t N, typename F >
|
||||
template < typename F >
|
||||
constexpr auto curry_or_apply(F&& f) {
|
||||
return curry_or_apply<N>(std::forward<F>(f), std::make_tuple());
|
||||
return curry_or_apply(std::forward<F>(f), std::make_tuple());
|
||||
}
|
||||
}
|
||||
|
||||
namespace kari_hpp
|
||||
{
|
||||
template < std::size_t N, typename F, typename... Args >
|
||||
template < typename F, typename... Args >
|
||||
struct curry_t final {
|
||||
template < typename U >
|
||||
constexpr curry_t(U&& u, std::tuple<Args...>&& args)
|
||||
: f_(std::forward<U>(u))
|
||||
, args_(std::move(args)) {}
|
||||
|
||||
// min_arity
|
||||
|
||||
constexpr std::size_t min_arity() const noexcept {
|
||||
return N;
|
||||
}
|
||||
|
||||
// recurry
|
||||
|
||||
template < std::size_t M >
|
||||
constexpr auto recurry() && {
|
||||
return detail::curry_or_apply<M>(
|
||||
return detail::curry_or_apply(
|
||||
std::move(f_),
|
||||
std::move(args_));
|
||||
}
|
||||
|
||||
template < std::size_t M >
|
||||
constexpr auto recurry() const & {
|
||||
return std::move(curry_t(*this)).template recurry<M>();
|
||||
return std::move(curry_t(*this)).recurry();
|
||||
}
|
||||
|
||||
// operator(As&&...)
|
||||
@@ -88,7 +80,7 @@ namespace kari_hpp
|
||||
|
||||
template < typename A >
|
||||
constexpr auto operator()(A&& a) && {
|
||||
return detail::curry_or_apply<(N > 0 ? N - 1 : 0)>(
|
||||
return detail::curry_or_apply(
|
||||
std::move(f_),
|
||||
std::tuple_cat(
|
||||
std::move(args_),
|
||||
@@ -121,7 +113,7 @@ namespace kari_hpp
|
||||
if constexpr ( is_curried_v<std::decay_t<F>> ) {
|
||||
return std::forward<F>(f);
|
||||
} else {
|
||||
return detail::curry_or_apply<0>(std::forward<F>(f));
|
||||
return detail::curry_or_apply(std::forward<F>(f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,44 +121,4 @@ namespace kari_hpp
|
||||
constexpr auto curry(F&& f, A&& a, As&&... as) {
|
||||
return curry(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
|
||||
}
|
||||
|
||||
//
|
||||
// curryV
|
||||
//
|
||||
|
||||
template < typename F >
|
||||
constexpr auto curryV(F&& f) {
|
||||
constexpr std::size_t max_n = std::size_t(-1);
|
||||
if constexpr ( is_curried_v<std::decay_t<F>> ) {
|
||||
return std::forward<F>(f).template recurry<max_n>();
|
||||
} else {
|
||||
return detail::curry_or_apply<max_n>(std::forward<F>(f));
|
||||
}
|
||||
}
|
||||
|
||||
template < typename F, typename A, typename... As >
|
||||
constexpr auto curryV(F&& f, A&& a, As&&... as) {
|
||||
return curryV(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
|
||||
}
|
||||
|
||||
//
|
||||
// curryN
|
||||
//
|
||||
|
||||
template < std::size_t N, typename F >
|
||||
constexpr auto curryN(F&& f) {
|
||||
if constexpr ( is_curried_v<std::decay_t<F>> ) {
|
||||
return std::forward<F>(f).template recurry<N>();
|
||||
} else {
|
||||
return detail::curry_or_apply<N>(std::forward<F>(f));
|
||||
}
|
||||
}
|
||||
|
||||
template < std::size_t N, typename F, typename A, typename... As >
|
||||
constexpr auto curryN(F&& f, A&& a, As&&... as) {
|
||||
constexpr std::size_t max_n = std::size_t(-1);
|
||||
constexpr std::size_t arg_n = sizeof...(As) + 1;
|
||||
static_assert(max_n - arg_n >= N, "invalid N argument");
|
||||
return curryN<N + arg_n>(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,24 +130,6 @@ TEST_CASE("kari") {
|
||||
REQUIRE(c5.v() == 15);
|
||||
REQUIRE(box_without_move<>::copyCount() == 40);
|
||||
}
|
||||
{
|
||||
box<>::resetCounters();
|
||||
curryV(plusV_gf())(box(1),box(2),box(3),box(4),box(5))();
|
||||
REQUIRE(box<>::moveCount() == 35);
|
||||
REQUIRE(box<>::copyCount() == 0);
|
||||
}
|
||||
{
|
||||
box<>::resetCounters();
|
||||
const auto c0 = curryV(plusV_gf());
|
||||
const auto c1 = c0(box(1));
|
||||
const auto c2 = c1(box(2));
|
||||
const auto c3 = c2(box(3));
|
||||
const auto c4 = c3(box(4));
|
||||
const auto c5 = c4(box(5));
|
||||
REQUIRE(c5().v() == 15);
|
||||
REQUIRE(box<>::moveCount() == 35);
|
||||
REQUIRE(box<>::copyCount() == 15);
|
||||
}
|
||||
}
|
||||
SUBCASE("persistent") {
|
||||
auto c = curry(minus3_gl);
|
||||
@@ -175,31 +157,6 @@ TEST_CASE("kari") {
|
||||
}
|
||||
|
||||
TEST_CASE("kari/curry") {
|
||||
SUBCASE("arity/min_arity") {
|
||||
REQUIRE(curry(minus3_gl).min_arity() == 0);
|
||||
REQUIRE(curryV(plusV_gf()).min_arity() == std::numeric_limits<std::size_t>::max());
|
||||
REQUIRE(curryN<3>(plusV_gf()).min_arity() == 3);
|
||||
REQUIRE(curryN<3>(plusV_gf())(1).min_arity() == 2);
|
||||
REQUIRE(curryN<3>(plusV_gf())(1)(2).min_arity() == 1);
|
||||
}
|
||||
SUBCASE("arity/recurring") {
|
||||
constexpr auto max_size_t = std::numeric_limits<std::size_t>::max();
|
||||
{
|
||||
REQUIRE(curry(curry(minus3_gl)).min_arity() == 0);
|
||||
REQUIRE(curry(curryV(plusV_gf())).min_arity() == max_size_t);
|
||||
REQUIRE(curry(curryN<3>(plusV_gf())).min_arity() == 3);
|
||||
}
|
||||
{
|
||||
REQUIRE(curryV(curry(minus3_gl)).min_arity() == max_size_t);
|
||||
REQUIRE(curryV(curryV(plusV_gf())).min_arity() == max_size_t);
|
||||
REQUIRE(curryV(curryN<3>(plusV_gf())).min_arity() == max_size_t);
|
||||
}
|
||||
{
|
||||
REQUIRE(curryN<2>(curry(minus3_gl)).min_arity() == 2);
|
||||
REQUIRE(curryN<2>(curryV(plusV_gf())).min_arity() == 2);
|
||||
REQUIRE(curryN<2>(curryN<3>(plusV_gf())).min_arity() == 2);
|
||||
}
|
||||
}
|
||||
SUBCASE("is_curried") {
|
||||
static_assert(!is_curried_v<void(int)>, "static unit test error");
|
||||
static_assert(!is_curried_v<decltype(minus2_gl)>, "static unit test error");
|
||||
@@ -307,68 +264,6 @@ TEST_CASE("kari/curry") {
|
||||
})(9)(4,3) == 2);
|
||||
}
|
||||
}
|
||||
SUBCASE("variadic_functions") {
|
||||
{
|
||||
const auto c = curry(plusV_gf());
|
||||
REQUIRE(c(15) == 15);
|
||||
REQUIRE(curry(plusV_gf(), 6) == 6);
|
||||
}
|
||||
{
|
||||
const auto c = curryV(plusV_gf());
|
||||
REQUIRE(c(1,2,3,4,5)() == 15);
|
||||
REQUIRE(curryV(plusV_gf(), 1, 2, 3)() == 6);
|
||||
}
|
||||
{
|
||||
const auto c = curryN<3>(plusV_gf());
|
||||
REQUIRE(c(1,2,3) == 6);
|
||||
REQUIRE(curryN<0>(plusV_gf(), 1, 2, 3) == 6);
|
||||
}
|
||||
{
|
||||
char buffer[256] = {'\0'};
|
||||
auto c = curryV(std::snprintf, buffer, 256, "%d + %d = %d");
|
||||
c(37, 5, 42)();
|
||||
REQUIRE(std::strcmp("37 + 5 = 42", buffer) == 0);
|
||||
}
|
||||
{
|
||||
char buffer[256] = {'\0'};
|
||||
auto c = curryN<3>(std::snprintf, buffer, 256, "%d + %d = %d");
|
||||
c(37, 5, 42);
|
||||
REQUIRE(std::strcmp("37 + 5 = 42", buffer) == 0);
|
||||
}
|
||||
}
|
||||
SUBCASE("variadic_functions/recurring") {
|
||||
{
|
||||
auto c0 = curry(curry(plusV_gf()));
|
||||
auto c1 = curry(curryV(plusV_gf()));
|
||||
auto c2 = curry(curryN<3>(plusV_gf()));
|
||||
REQUIRE(c0(42) == 42);
|
||||
REQUIRE(c1(40,2)() == 42);
|
||||
REQUIRE(c2(37,2,3) == 42);
|
||||
}
|
||||
{
|
||||
auto c0 = curryV(curry(plusV_gf()));
|
||||
auto c1 = curryV(curryV(plusV_gf()));
|
||||
auto c2 = curryV(curryN<3>(plusV_gf()));
|
||||
REQUIRE(c0(40,2)() == 42);
|
||||
REQUIRE(c1(40,2)() == 42);
|
||||
REQUIRE(c2(40,2)() == 42);
|
||||
}
|
||||
{
|
||||
auto c0 = curryN<2>(curry(plusV_gf()));
|
||||
auto c1 = curryN<2>(curryV(plusV_gf()));
|
||||
auto c2 = curryN<2>(curryN<3>(plusV_gf()));
|
||||
auto c3 = curryN<4>(curryN<3>(plusV_gf()));
|
||||
REQUIRE(c0(40,2) == 42);
|
||||
REQUIRE(c1(40,2) == 42);
|
||||
REQUIRE(c2(40,2) == 42);
|
||||
REQUIRE(c3(20,15,5,2) == 42);
|
||||
}
|
||||
{
|
||||
auto c0 = curry(plusV_gf());
|
||||
auto c1 = curryN<2>(c0);
|
||||
REQUIRE(c1(40,2) == 42);
|
||||
}
|
||||
}
|
||||
SUBCASE("member_functions") {
|
||||
{
|
||||
auto c0 = curry(&box<>::addV);
|
||||
@@ -414,8 +309,8 @@ namespace kari_regression {
|
||||
template < typename C >
|
||||
struct first_type_impl;
|
||||
|
||||
template < std::size_t N, typename F, typename A, typename... Args >
|
||||
struct first_type_impl<curry_t<N, F, A, Args...>> {
|
||||
template < typename F, typename A, typename... Args >
|
||||
struct first_type_impl<curry_t<F, A, Args...>> {
|
||||
using type = A;
|
||||
};
|
||||
|
||||
@@ -440,9 +335,4 @@ TEST_CASE("kari_regression") {
|
||||
typename first_type<decltype(c2)>::type
|
||||
>::value,"static unit test error");
|
||||
}
|
||||
SUBCASE("curryN_already_curried_function") {
|
||||
auto c = curryN<3>(plusV_gf());
|
||||
auto c2 = curryN<3>(c);
|
||||
REQUIRE(c2(1,2,3) == 6);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,25 +67,6 @@ namespace kari_tests
|
||||
return v1 - v2 - v3;
|
||||
}
|
||||
};
|
||||
|
||||
struct plusV_gf {
|
||||
template < typename A >
|
||||
constexpr decltype(auto) operator()(A&& a) const {
|
||||
return std::forward<A>(a);
|
||||
}
|
||||
|
||||
template < typename A, typename B >
|
||||
constexpr decltype(auto) operator()(A&& a, B&& b) const {
|
||||
return std::forward<A>(a) + std::forward<B>(b);
|
||||
}
|
||||
|
||||
template < typename A, typename B, typename... Cs >
|
||||
constexpr decltype(auto) operator()(A&& a, B&& b, Cs&&... cs) const {
|
||||
return (*this)(
|
||||
(*this)(std::forward<A>(a), std::forward<B>(b)),
|
||||
std::forward<Cs>(cs)...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace kari_tests
|
||||
|
||||
Reference in New Issue
Block a user