From 3e5829ca43d2fe388006f76db25da06793ac86a0 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 31 Oct 2015 13:54:31 -0500 Subject: [PATCH 01/17] Move can_be_called to a seperate header --- fit/compress.h | 8 +-- fit/detail/can_be_called.h | 103 +++++++++++++++++++++++++++++++++++++ fit/detail/result_of.h | 6 +-- fit/is_callable.h | 96 +--------------------------------- fit/reverse_compress.h | 8 +-- 5 files changed, 116 insertions(+), 105 deletions(-) create mode 100644 fit/detail/can_be_called.h diff --git a/fit/compress.h b/fit/compress.h index 6498a81..02a63b0 100644 --- a/fit/compress.h +++ b/fit/compress.h @@ -44,7 +44,7 @@ /// /// State must be: /// -/// * MoveConstructible +/// * CopyConstructible /// /// F must be: /// @@ -107,18 +107,18 @@ struct compress_adaptor } template - constexpr const State& get_state(Ts&&... xs) const + constexpr State get_state(Ts&&... xs) const { return this->second(xs...); } template - constexpr FIT_SFINAE_RESULT(detail::v_fold, id_, id_, id_...) + constexpr FIT_SFINAE_RESULT(detail::v_fold, id_, id_, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::v_fold()( FIT_MANGLE_CAST(const F&)(this->base_function(xs...)), - FIT_MANGLE_CAST(State&&)(fit::move(this->get_state(xs...))), + FIT_MANGLE_CAST(State)(this->get_state(xs...)), fit::forward(xs)... ) ) diff --git a/fit/detail/can_be_called.h b/fit/detail/can_be_called.h new file mode 100644 index 0000000..23ae711 --- /dev/null +++ b/fit/detail/can_be_called.h @@ -0,0 +1,103 @@ +/*============================================================================= + Copyright (c) 2015 Paul Fultz II + can_be_called.h + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef FIT_GUARD_CAN_BE_CALLED_H +#define FIT_GUARD_CAN_BE_CALLED_H + +#include +#include +#include + +namespace fit { namespace detail { + +#if FIT_NO_EXPRESSION_SFINAE +struct dont_care +{ + dont_care(...); +}; + +template +struct never_care +{ + typedef dont_care type; +}; + +struct cant_be_called_type +{}; + +template +struct is_callable_wrapper : std::remove_cv::type>::type +{ + is_callable_wrapper(); + typedef cant_be_called_type const &(*pointer_to_function)(typename never_care::type...); + operator pointer_to_function() const; +}; + +template +struct not_ +: std::integral_constant +{}; + +template +struct can_be_called +: not_()(std::declval()...) +)>::type>> +{}; + +template +struct check_args; + +template +struct check_args +: and_...> +{}; + +template +struct can_be_called +: std::conditional, + std::false_type +>::type +{}; + +template +struct can_be_called +: std::conditional, + std::false_type +>::type +{}; + +#else + +template +struct callable_args +{}; + +template +struct can_be_called_impl +: std::false_type +{}; + +template +struct can_be_called_impl, typename detail::holder< + decltype( std::declval()(std::declval()...) ) +>::type> +: std::true_type +{}; + +template +struct can_be_called +: can_be_called_impl> +{}; + +#endif + +}} + +#endif diff --git a/fit/detail/result_of.h b/fit/detail/result_of.h index 8ba29fd..916b03c 100644 --- a/fit/detail/result_of.h +++ b/fit/detail/result_of.h @@ -21,9 +21,9 @@ #if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE -#include -#include +#include #include +#include namespace fit { namespace detail { @@ -34,7 +34,7 @@ template struct result_of_impl< F, holder, - typename std::enable_if::value>::type + typename std::enable_if::value>::type > { typedef decltype(std::declval()(std::declval()...)) type; diff --git a/fit/is_callable.h b/fit/is_callable.h index b3d4548..1fd6b7b 100644 --- a/fit/is_callable.h +++ b/fit/is_callable.h @@ -36,108 +36,16 @@ /// static_assert(is_callable(), "Not callable"); /// -#include -#include -#include -#include -#include + +#include namespace fit { -#if FIT_NO_EXPRESSION_SFINAE -namespace detail { - -struct dont_care -{ - dont_care(...); -}; - -template -struct never_care -{ - typedef dont_care type; -}; - -struct cant_be_called_type -{}; - -template -struct is_callable_wrapper : std::remove_cv::type>::type -{ - is_callable_wrapper(); - typedef cant_be_called_type const &(*pointer_to_function)(typename never_care::type...); - operator pointer_to_function() const; -}; - -template -struct not_ -: std::integral_constant -{}; - -template -struct can_be_called -: not_()(std::declval()...) -)>::type>> -{}; - -template -struct check_args; - -template -struct check_args -: and_...> -{}; - -template -struct can_be_called -: std::conditional, - std::false_type ->::type -{}; - -template -struct can_be_called -: std::conditional, - std::false_type ->::type -{}; -} - template struct is_callable : detail::can_be_called {}; -#else -namespace detail { -template -struct callable_args -{}; - -template -struct is_callable_impl -: std::false_type -{}; - -template -struct is_callable_impl, typename detail::holder< - decltype( std::declval()(std::declval()...) ) ->::type> -: std::true_type -{}; -} - - -template -struct is_callable -: detail::is_callable_impl> -{}; - -#endif - } #endif diff --git a/fit/reverse_compress.h b/fit/reverse_compress.h index 1c47435..40e93d9 100644 --- a/fit/reverse_compress.h +++ b/fit/reverse_compress.h @@ -45,7 +45,7 @@ /// /// State must be: /// -/// * MoveConstructible +/// * CopyConstructible /// /// F must be: /// @@ -108,18 +108,18 @@ struct reverse_compress_adaptor } template - constexpr const State& get_state(Ts&&... xs) const + constexpr State get_state(Ts&&... xs) const { return this->second(xs...); } template - constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_, id_, id_...) + constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_, id_, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::v_reverse_fold()( FIT_MANGLE_CAST(const F&)(this->base_function(xs...)), - FIT_MANGLE_CAST(State&&)(fit::move(this->get_state(xs...))), + FIT_MANGLE_CAST(State)(this->get_state(xs...)), fit::forward(xs)... ) ) From e1241684f92ce9de49539ab93f94bb2df2db3596 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 31 Oct 2015 15:24:51 -0500 Subject: [PATCH 02/17] Add support for general callables in apply --- fit/apply.h | 89 +++++++++++++++++++++++++++++++++++++- fit/detail/can_be_called.h | 10 ++++- test/apply.cpp | 49 +++++++++++++++++++++ 3 files changed, 146 insertions(+), 2 deletions(-) diff --git a/fit/apply.h b/fit/apply.h index 133a62c..5f4ecee 100644 --- a/fit/apply.h +++ b/fit/apply.h @@ -55,11 +55,98 @@ namespace fit { namespace detail { +#if FIT_NO_EXPRESSION_SFINAE +struct apply_mem_fn +{ + +#define FIT_APPLY_MEM_FN_CALL(cv) \ + template ::type>, \ + std::is_convertible... \ + >::value>::type> \ + constexpr R operator()(R (Base::*mf)(Ts...) cv, Derived&& ref, Us &&... xs) const \ + { \ + return (fit::forward(ref).*mf)(fit::forward(xs)...); \ + } + FIT_APPLY_MEM_FN_CALL() + FIT_APPLY_MEM_FN_CALL(const) + FIT_APPLY_MEM_FN_CALL(volatile) + FIT_APPLY_MEM_FN_CALL(const volatile) +}; + +struct apply_mem_data +{ + template ::type>::value + )>::type> + constexpr R operator()(R Base::*pmd, Derived&& ref) const + { + return fit::forward(ref).*pmd; + } +}; +#endif struct apply_f { +#if FIT_NO_EXPRESSION_SFINAE + template::type>::value + )>::type> + constexpr FIT_SFINAE_RESULT(apply_mem_fn, id_, id_, id_...) + operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_RETURNS + ( + apply_mem_fn()(f, fit::forward(obj), fit::forward(xs)...) + ); + + template::type>::value + )>::type> + constexpr FIT_SFINAE_RESULT(apply_mem_fn, id_, id_())>, id_...) + operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_RETURNS + ( + apply_mem_fn()(f, *fit::forward(obj), fit::forward(xs)...) + ); + + template::type>::value + )>::type> + constexpr FIT_SFINAE_RESULT(apply_mem_data, id_, id_) + operator()(F&& f, T&& obj) const FIT_SFINAE_RETURNS + ( + apply_mem_data()(f, fit::forward(obj)) + ); + + template::type>::value + )>::type> + constexpr FIT_SFINAE_RESULT(apply_mem_data, id_, id_())>) + operator()(F&& f, T&& obj) const FIT_SFINAE_RETURNS + ( + apply_mem_data()(f, *fit::forward(obj)) + ); + +#else + + template + constexpr auto operator()(T Base::*pmd, Derived&& ref) const + FIT_RETURNS(fit::forward(ref).*pmd); + + template + constexpr auto operator()(PMD&& pmd, Pointer&& ptr) const + FIT_RETURNS((*fit::forward(ptr)).*fit::forward(pmd)); + + template + constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const + FIT_RETURNS((fit::forward(ref).*pmf)(fit::forward(args)...)); + + template + constexpr auto operator()(PMF&& pmf, Pointer&& ptr, Args&&... args) const + FIT_RETURNS(((*fit::forward(ptr)).*fit::forward(pmf))(fit::forward(args)...)); + +#endif template - constexpr FIT_SFINAE_RESULT(F, id_...) operator()(F&& f, Ts&&... xs) const FIT_SFINAE_RETURNS + constexpr FIT_SFINAE_RESULT(F, id_...) + operator()(F&& f, Ts&&... xs) const FIT_SFINAE_RETURNS ( f(fit::forward(xs)...) ); diff --git a/fit/detail/can_be_called.h b/fit/detail/can_be_called.h index 23ae711..a6d5f6d 100644 --- a/fit/detail/can_be_called.h +++ b/fit/detail/can_be_called.h @@ -29,8 +29,16 @@ struct never_care struct cant_be_called_type {}; +struct no_type +{}; + +template::type>::type> +struct is_callable_wrapper_base +: std::conditional::value, U, no_type> +{}; + template -struct is_callable_wrapper : std::remove_cv::type>::type +struct is_callable_wrapper : is_callable_wrapper_base::type { is_callable_wrapper(); typedef cant_be_called_type const &(*pointer_to_function)(typename never_care::type...); diff --git a/test/apply.cpp b/test/apply.cpp index 06a25f3..eaa21ae 100644 --- a/test/apply.cpp +++ b/test/apply.cpp @@ -6,3 +6,52 @@ FIT_TEST_CASE() FIT_STATIC_TEST_CHECK(fit::apply(binary_class(), 1, 2) == 3); FIT_TEST_CHECK(fit::apply(binary_class(), 1, 2) == 3); } + +struct member_sum_f +{ + int i; + constexpr member_sum_f(int x) : i(x) + {} + + constexpr int add(int x) const + { + return i+x; + } +}; + +struct member_sum_f_derived +: member_sum_f +{ + constexpr member_sum_f_derived(int x) : member_sum_f(x) + {} +}; + +FIT_TEST_CASE() +{ + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); + FIT_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); + + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); + FIT_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); + + std::unique_ptr msp(new member_sum_f(1)); + FIT_TEST_CHECK(fit::apply(&member_sum_f::add, msp, 2) == 3); + + std::unique_ptr mspd(new member_sum_f_derived(1)); + FIT_TEST_CHECK(fit::apply(&member_sum_f::add, mspd, 2) == 3); +} + +FIT_TEST_CASE() +{ + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3); + FIT_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3); + + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); + FIT_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); + + std::unique_ptr msp(new member_sum_f(3)); + FIT_TEST_CHECK(fit::apply(&member_sum_f::i, msp) == 3); + + std::unique_ptr mspd(new member_sum_f_derived(3)); + FIT_TEST_CHECK(fit::apply(&member_sum_f::i, mspd) == 3); +} From bbb89bbbd23f1b516ca63c0096865e3a2bd8d5d6 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 31 Oct 2015 15:33:01 -0500 Subject: [PATCH 03/17] Member function pointers can only be constexpr in clang --- test/apply.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/apply.cpp b/test/apply.cpp index eaa21ae..ae90669 100644 --- a/test/apply.cpp +++ b/test/apply.cpp @@ -28,12 +28,14 @@ struct member_sum_f_derived FIT_TEST_CASE() { - FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); FIT_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); - - FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); FIT_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); +#ifdef __clang__ + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); +#endif + std::unique_ptr msp(new member_sum_f(1)); FIT_TEST_CHECK(fit::apply(&member_sum_f::add, msp, 2) == 3); @@ -43,12 +45,14 @@ FIT_TEST_CASE() FIT_TEST_CASE() { - FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3); FIT_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3); - - FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); FIT_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); +#ifdef __clang__ + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f(3)) == 3); + FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); +#endif + std::unique_ptr msp(new member_sum_f(3)); FIT_TEST_CHECK(fit::apply(&member_sum_f::i, msp) == 3); From 2fe70a9ebc23680ca4b662f88b1e272c27dc718e Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 31 Oct 2015 15:55:37 -0500 Subject: [PATCH 04/17] Use manual sfinae --- fit/apply.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/fit/apply.h b/fit/apply.h index 5f4ecee..ab53fbd 100644 --- a/fit/apply.h +++ b/fit/apply.h @@ -52,10 +52,11 @@ #include #include + namespace fit { namespace detail { -#if FIT_NO_EXPRESSION_SFINAE +#if FIT_HAS_MANUAL_DEDUCTION struct apply_mem_fn { @@ -88,12 +89,12 @@ struct apply_mem_data struct apply_f { -#if FIT_NO_EXPRESSION_SFINAE +#if FIT_HAS_MANUAL_DEDUCTION template::type>::value )>::type> - constexpr FIT_SFINAE_RESULT(apply_mem_fn, id_, id_, id_...) - operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_RETURNS + constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_fn, id_, id_, id_...) + operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_MANUAL_RETURNS ( apply_mem_fn()(f, fit::forward(obj), fit::forward(xs)...) ); @@ -101,8 +102,8 @@ struct apply_f template::type>::value )>::type> - constexpr FIT_SFINAE_RESULT(apply_mem_fn, id_, id_())>, id_...) - operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_RETURNS + constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_fn, id_, id_())>, id_...) + operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_MANUAL_RETURNS ( apply_mem_fn()(f, *fit::forward(obj), fit::forward(xs)...) ); @@ -110,8 +111,8 @@ struct apply_f template::type>::value )>::type> - constexpr FIT_SFINAE_RESULT(apply_mem_data, id_, id_) - operator()(F&& f, T&& obj) const FIT_SFINAE_RETURNS + constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_data, id_, id_) + operator()(F&& f, T&& obj) const FIT_SFINAE_MANUAL_RETURNS ( apply_mem_data()(f, fit::forward(obj)) ); @@ -119,8 +120,8 @@ struct apply_f template::type>::value )>::type> - constexpr FIT_SFINAE_RESULT(apply_mem_data, id_, id_())>) - operator()(F&& f, T&& obj) const FIT_SFINAE_RETURNS + constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_data, id_, id_())>) + operator()(F&& f, T&& obj) const FIT_SFINAE_MANUAL_RETURNS ( apply_mem_data()(f, *fit::forward(obj)) ); From 60c162e5ea9b5ef2751715b1f3709727a0e3f030 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 31 Oct 2015 15:59:53 -0500 Subject: [PATCH 05/17] Add proper ifdefs --- fit/apply.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fit/apply.h b/fit/apply.h index ab53fbd..59e781e 100644 --- a/fit/apply.h +++ b/fit/apply.h @@ -56,7 +56,7 @@ namespace fit { namespace detail { -#if FIT_HAS_MANUAL_DEDUCTION +#if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE struct apply_mem_fn { @@ -89,7 +89,7 @@ struct apply_mem_data struct apply_f { -#if FIT_HAS_MANUAL_DEDUCTION +#if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE template::type>::value )>::type> From a695f3b31cd1722c46bab0a26618a31ba908d1ab Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 1 Nov 2015 17:35:04 -0600 Subject: [PATCH 06/17] Add workaround for gcc 4.6 --- fit/apply.h | 25 ++++++++++++++++++++----- test/apply.cpp | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fit/apply.h b/fit/apply.h index 59e781e..99673ea 100644 --- a/fit/apply.h +++ b/fit/apply.h @@ -59,11 +59,21 @@ namespace detail { #if FIT_HAS_MANUAL_DEDUCTION || FIT_NO_EXPRESSION_SFINAE struct apply_mem_fn { + template + struct convertible_args; + + template + struct is_convertible_args; + + template + struct is_convertible_args, convertible_args> + : and_...> + {}; #define FIT_APPLY_MEM_FN_CALL(cv) \ template ::type>, \ - std::is_convertible... \ + is_convertible_args, convertible_args> \ >::value>::type> \ constexpr R operator()(R (Base::*mf)(Ts...) cv, Derived&& ref, Us &&... xs) const \ { \ @@ -85,6 +95,11 @@ struct apply_mem_data return fit::forward(ref).*pmd; } }; + +template())> +struct apply_deref +{ typedef U type; }; + #endif struct apply_f @@ -99,10 +114,10 @@ struct apply_f apply_mem_fn()(f, fit::forward(obj), fit::forward(xs)...) ); - template::type, class=typename std::enable_if<( std::is_member_function_pointer::type>::value )>::type> - constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_fn, id_, id_())>, id_...) + constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_fn, id_, id_, id_...) operator()(F&& f, T&& obj, Ts&&... xs) const FIT_SFINAE_MANUAL_RETURNS ( apply_mem_fn()(f, *fit::forward(obj), fit::forward(xs)...) @@ -117,10 +132,10 @@ struct apply_f apply_mem_data()(f, fit::forward(obj)) ); - template::type, class=typename std::enable_if<( std::is_member_object_pointer::type>::value )>::type> - constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_data, id_, id_())>) + constexpr FIT_SFINAE_MANUAL_RESULT(apply_mem_data, id_, id_) operator()(F&& f, T&& obj) const FIT_SFINAE_MANUAL_RETURNS ( apply_mem_data()(f, *fit::forward(obj)) diff --git a/test/apply.cpp b/test/apply.cpp index ae90669..886fdf2 100644 --- a/test/apply.cpp +++ b/test/apply.cpp @@ -36,6 +36,7 @@ FIT_TEST_CASE() FIT_STATIC_TEST_CHECK(fit::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); #endif + static_assert(std::is_base_of::value, "Base of failed"); std::unique_ptr msp(new member_sum_f(1)); FIT_TEST_CHECK(fit::apply(&member_sum_f::add, msp, 2) == 3); From 35f73e80b1452234802bcc05dbf539484c61650c Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 19 Nov 2015 21:44:12 -0600 Subject: [PATCH 07/17] Support callable for by adaptor --- fit/apply_eval.h | 9 +++++---- fit/by.h | 34 +++++++++++++++++----------------- test/by.cpp | 11 +++++++++++ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/fit/apply_eval.h b/fit/apply_eval.h index 8d90547..ae613bb 100644 --- a/fit/apply_eval.h +++ b/fit/apply_eval.h @@ -57,6 +57,7 @@ #include #include #include +#include #include #ifndef FIT_NO_ORDERD_BRACE_INIT @@ -95,7 +96,7 @@ struct eval_helper R result; template - constexpr eval_helper(const F& f, Ts&&... xs) : result(f(fit::forward(xs)...)) + constexpr eval_helper(const F& f, Ts&&... xs) : result(apply(f, fit::forward(xs)...)) {} constexpr R get_result() @@ -109,7 +110,7 @@ struct eval_helper { int x; template - constexpr eval_helper(const F& f, Ts&&... xs) : x(f(fit::forward(xs)...), 0) + constexpr eval_helper(const F& f, Ts&&... xs) : x(apply(f, fit::forward(xs)...), 0) {} }; #endif @@ -117,7 +118,7 @@ struct eval_helper struct apply_eval_f { template()(fit::eval(std::declval())...) + apply(std::declval(), fit::eval(std::declval())...) ), class=typename std::enable_if<(!std::is_void::value)>::type > @@ -134,7 +135,7 @@ struct apply_eval_f } template()(fit::eval(std::declval())...) + apply(std::declval(), fit::eval(std::declval())...) ), class=typename std::enable_if<(std::is_void::value)>::type > diff --git a/fit/by.h b/fit/by.h index a5b76cc..d7f65c9 100644 --- a/fit/by.h +++ b/fit/by.h @@ -67,7 +67,7 @@ #include #include -#include +#include #include #include #include @@ -160,17 +160,17 @@ template struct by_adaptor; template -struct by_adaptor : Projection, F +struct by_adaptor : detail::callable_base, detail::callable_base { typedef by_adaptor fit_rewritable_tag; template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } template - constexpr const Projection& base_projection(Ts&&... xs) const + constexpr const detail::callable_base& base_projection(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -182,51 +182,51 @@ struct by_adaptor : Projection, F { template struct of - : Failure::template of()(std::declval()))...> + : Failure::template of>()(std::declval()))...> {}; }; }; struct failure - : failure_map + : failure_map> {}; - FIT_INHERIT_DEFAULT(by_adaptor, Projection, F) + FIT_INHERIT_DEFAULT(by_adaptor, detail::callable_base, F) - template + template), FIT_ENABLE_IF_CONVERTIBLE(G, detail::callable_base)> constexpr by_adaptor(P&& p, G&& f) - : Projection(fit::forward

(p)), F(fit::forward(f)) + : detail::callable_base(fit::forward

(p)), detail::callable_base(fit::forward(f)) {} FIT_RETURNS_CLASS(by_adaptor); template - constexpr FIT_SFINAE_RESULT(const F&, result_of>...) + constexpr FIT_SFINAE_RESULT(const detail::callable_base&, result_of&, id_>...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::by_eval( - FIT_MANGLE_CAST(const Projection&)(FIT_CONST_THIS->base_projection(xs...)), - FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)), + FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_projection(xs...)), + FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(xs...)), fit::forward(xs)... ) ); }; template -struct by_adaptor : Projection +struct by_adaptor : detail::callable_base { typedef by_adaptor fit_rewritable1_tag; template - constexpr const Projection& base_projection(Ts&&... xs) const + constexpr const detail::callable_base& base_projection(Ts&&... xs) const { return always_ref(*this)(xs...); } - FIT_INHERIT_DEFAULT(by_adaptor, Projection) + FIT_INHERIT_DEFAULT(by_adaptor, detail::callable_base) - template + template)> constexpr by_adaptor(P&& p) - : Projection(fit::forward

(p)) + : detail::callable_base(fit::forward

(p)) {} FIT_RETURNS_CLASS(by_adaptor); diff --git a/test/by.cpp b/test/by.cpp index 1436e20..16a0096 100644 --- a/test/by.cpp +++ b/test/by.cpp @@ -31,6 +31,17 @@ FIT_TEST_CASE() static_assert(fit::detail::is_default_constructible::value, "Not default constructible"); } +FIT_TEST_CASE() +{ +#ifndef _MSC_VER + constexpr +#endif + auto add = fit::_ + fit::_; + FIT_STATIC_TEST_CHECK(fit::by(select_x(), add)(foo(1), foo(2)) == 3); + FIT_TEST_CHECK(fit::by(&foo::x, add)(foo(1), foo(2)) == 3); + static_assert(fit::detail::is_default_constructible::value, "Not default constructible"); +} + FIT_TEST_CASE() { auto indirect_add = fit::by(*fit::_, fit::_ + fit::_); From 011949d4dd35d695ae90357681d96e5fc92b2367 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 19 Nov 2015 21:53:35 -0600 Subject: [PATCH 08/17] Add callable to capture --- fit/capture.h | 14 +++++++------- test/capture.cpp | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/fit/capture.h b/fit/capture.h index 7af23de..fb8c0bd 100644 --- a/fit/capture.h +++ b/fit/capture.h @@ -8,7 +8,7 @@ #ifndef FIT_GUARD_CAPTURE_H #define FIT_GUARD_CAPTURE_H -#include +#include #include #include #include @@ -67,14 +67,14 @@ namespace fit { namespace detail { template -struct capture_invoke : F, Pack +struct capture_invoke : detail::callable_base, Pack { typedef capture_invoke fit_rewritable1_tag; template - constexpr capture_invoke(X&& x, Y&& y) : F(fit::forward(x)), Pack(fit::forward(y)) + constexpr capture_invoke(X&& x, Y&& y) : detail::callable_base(fit::forward(x)), Pack(fit::forward(y)) {} template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -108,7 +108,7 @@ struct capture_invoke : F, Pack }; struct failure - : failure_map + : failure_map> {}; FIT_RETURNS_CLASS(capture_invoke); @@ -120,7 +120,7 @@ struct capture_invoke : F, Pack id_, result_of...> >::type, - id_ + id_&&> ) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( @@ -129,7 +129,7 @@ struct capture_invoke : F, Pack FIT_MANGLE_CAST(const Pack&)(FIT_CONST_THIS->get_pack(xs...)), fit::pack_forward(fit::forward(xs)...) ) - (FIT_RETURNS_C_CAST(F&&)(FIT_CONST_THIS->base_function(xs...))) + (FIT_RETURNS_C_CAST(detail::callable_base&&)(FIT_CONST_THIS->base_function(xs...))) ); }; diff --git a/test/capture.cpp b/test/capture.cpp index 96d50c0..186e49c 100644 --- a/test/capture.cpp +++ b/test/capture.cpp @@ -25,4 +25,24 @@ FIT_TEST_CASE() FIT_STATIC_TEST_CHECK(fit::capture_decay(1)(binary_class())(2) == 3); FIT_TEST_CHECK(fit::capture_decay(1)(binary_class())(2) == 3); -} \ No newline at end of file +} + +struct add_member +{ + int i; + + add_member(int i) : i(i) + {} + + int add(int j) const + { + return i + j; + } +}; + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::capture(add_member(1), 2)(&add_member::add)() == 3); + FIT_TEST_CHECK(fit::capture(add_member(1))(&add_member::add)(2) == 3); +} + From 58acf38303354a5c596f881c77d05abb683ac108 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 19 Nov 2015 21:54:07 -0600 Subject: [PATCH 09/17] Add missing header --- fit/detail/callable_base.h | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 fit/detail/callable_base.h diff --git a/fit/detail/callable_base.h b/fit/detail/callable_base.h new file mode 100644 index 0000000..4e35c2f --- /dev/null +++ b/fit/detail/callable_base.h @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2015 Paul Fultz II + callable_base.h + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef FIT_GUARD_CALLABLE_BASE_H +#define FIT_GUARD_CALLABLE_BASE_H + +#include +#include +#include + +#ifndef FIT_HAS_TEMPLATE_ALIAS +#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) +#define FIT_HAS_TEMPLATE_ALIAS 0 +#else +#define FIT_HAS_TEMPLATE_ALIAS 1 +#endif +#endif + +namespace fit { namespace detail { + +template +struct non_class_function +{ + F f; + FIT_DELGATE_CONSTRUCTOR(non_class_function, F, f) + + template + constexpr FIT_SFINAE_RESULT(apply_f, id_, id_...) + operator()(Ts&&... xs) const FIT_SFINAE_RETURNS + ( + fit::apply(f, fit::forward(xs)...) + ); +}; + +#if FIT_HAS_TEMPLATE_ALIAS +template +using callable_base = typename std::conditional<(std::is_class::value), F, non_class_function>::type; +#else +template::value), F, non_class_function>::type> +struct callable_base +: Base +{ + FIT_INHERIT_CONSTRUCTOR(callable_basse, Base) +}; +#endif + +}} + +#endif \ No newline at end of file From 03e4a763a91602f12f031e5cee5f9790ebefcb09 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 19 Nov 2015 22:00:58 -0600 Subject: [PATCH 10/17] Add callable to combine and compose --- fit/combine.h | 6 +++--- fit/compose.h | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fit/combine.h b/fit/combine.h index c3ca48f..0ad68db 100644 --- a/fit/combine.h +++ b/fit/combine.h @@ -49,7 +49,7 @@ #include #include -#include +#include #include namespace fit { namespace detail { @@ -106,9 +106,9 @@ struct combine_adaptor_base, F, Gs...> template struct combine_adaptor -: detail::combine_adaptor_base::type, F, Gs...> +: detail::combine_adaptor_base::type, detail::callable_base, detail::callable_base...> { - typedef detail::combine_adaptor_base::type, F, Gs...> base_type; + typedef detail::combine_adaptor_base::type, detail::callable_base, detail::callable_base...> base_type; FIT_INHERIT_CONSTRUCTOR(combine_adaptor, base_type) }; diff --git a/fit/compose.h b/fit/compose.h index a703357..11078b8 100644 --- a/fit/compose.h +++ b/fit/compose.h @@ -64,7 +64,7 @@ /// assert(r == 4); /// -#include +#include #include #include #include @@ -97,30 +97,30 @@ struct compose_kernel : detail::compressed_pair } template -struct compose_adaptor : detail::compose_kernel +struct compose_adaptor : detail::compose_kernel, FIT_JOIN(compose_adaptor, detail::callable_base...)> { typedef compose_adaptor fit_rewritable_tag; - typedef FIT_JOIN(compose_adaptor, Fs...) tail; - typedef detail::compose_kernel base_type; + typedef FIT_JOIN(compose_adaptor, detail::callable_base...) tail; + typedef detail::compose_kernel, tail> base_type; FIT_INHERIT_DEFAULT(compose_adaptor, base_type) - template + template), FIT_ENABLE_IF_CONSTRUCTIBLE(tail, Xs...)> constexpr compose_adaptor(X&& f1, Xs&& ... fs) : base_type(fit::forward(f1), tail(fit::forward(fs)...)) {} }; template -struct compose_adaptor : F +struct compose_adaptor : detail::callable_base { typedef compose_adaptor fit_rewritable_tag; - FIT_INHERIT_DEFAULT(compose_adaptor, F) + FIT_INHERIT_DEFAULT(compose_adaptor, detail::callable_base) - template + template)> constexpr compose_adaptor(X&& f1) - : F(fit::forward(f1)) + : detail::callable_base(fit::forward(f1)) {} }; From 5ec997472e87397a79cbaf06367f5efdba636576 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 25 Nov 2015 18:00:10 -0500 Subject: [PATCH 11/17] Add more callable to more function adaptors --- fit/compress.h | 22 +++++++++++----------- fit/conditional.h | 14 +++++++------- fit/decorate.h | 12 ++++++------ fit/fix.h | 14 +++++++------- fit/flip.h | 12 ++++++------ fit/flow.h | 20 ++++++++++---------- fit/if.h | 6 +++--- fit/indirect.h | 2 +- fit/infix.h | 12 ++++++------ fit/lazy.h | 10 +++++----- fit/match.h | 17 +++++++++-------- fit/protect.h | 4 ++-- fit/result.h | 16 ++++++++-------- fit/reveal.h | 9 +++++---- fit/reverse_compress.h | 22 +++++++++++----------- fit/rotate.h | 12 ++++++------ fit/tap.h | 3 ++- fit/unpack.h | 12 ++++++------ 18 files changed, 111 insertions(+), 108 deletions(-) diff --git a/fit/compress.h b/fit/compress.h index 02a63b0..15c3202 100644 --- a/fit/compress.h +++ b/fit/compress.h @@ -65,7 +65,7 @@ /// assert(fit::compress(max_f())(2, 3, 4, 5) == 5); /// -#include +#include #include #include #include @@ -95,13 +95,13 @@ struct v_fold template struct compress_adaptor -: detail::compressed_pair +: detail::compressed_pair, State> { - typedef detail::compressed_pair base_type; + typedef detail::compressed_pair, State> base_type; FIT_INHERIT_CONSTRUCTOR(compress_adaptor, base_type) template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return this->first(xs...); } @@ -113,11 +113,11 @@ struct compress_adaptor } template - constexpr FIT_SFINAE_RESULT(detail::v_fold, id_, id_, id_...) + constexpr FIT_SFINAE_RESULT(detail::v_fold, id_&>, id_, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::v_fold()( - FIT_MANGLE_CAST(const F&)(this->base_function(xs...)), + FIT_MANGLE_CAST(const detail::callable_base&)(this->base_function(xs...)), FIT_MANGLE_CAST(State)(this->get_state(xs...)), fit::forward(xs)... ) @@ -127,22 +127,22 @@ struct compress_adaptor template struct compress_adaptor -: F +: detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(compress_adaptor, F) + FIT_INHERIT_CONSTRUCTOR(compress_adaptor, detail::callable_base) template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } template - constexpr FIT_SFINAE_RESULT(detail::v_fold, id_, id_...) + constexpr FIT_SFINAE_RESULT(detail::v_fold, id_&>, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::v_fold()( - FIT_MANGLE_CAST(const F&)(this->base_function(xs...)), + FIT_MANGLE_CAST(const detail::callable_base&)(this->base_function(xs...)), fit::forward(xs)... ) ) diff --git a/fit/conditional.h b/fit/conditional.h index 12633da..f8018fa 100644 --- a/fit/conditional.h +++ b/fit/conditional.h @@ -68,7 +68,7 @@ /// to how the function is chosen. #include -#include +#include #include #include #include @@ -106,14 +106,14 @@ struct conditional_adaptor_base : conditional_adaptor_base, c }; template -struct conditional_adaptor_base : F +struct conditional_adaptor_base : detail::callable_base { - typedef F base; + typedef detail::callable_base base; - FIT_INHERIT_CONSTRUCTOR(conditional_adaptor_base, F); + FIT_INHERIT_CONSTRUCTOR(conditional_adaptor_base, detail::callable_base); template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -121,10 +121,10 @@ struct conditional_adaptor_base : F FIT_RETURNS_CLASS(conditional_adaptor_base); template - constexpr FIT_SFINAE_RESULT(const F&, id_...) + constexpr FIT_SFINAE_RESULT(const detail::callable_base&, id_...) operator()(rank, Ts&&... xs) const FIT_SFINAE_RETURNS ( - (FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward(xs)...) + (FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward(xs)...) ); }; diff --git a/fit/decorate.h b/fit/decorate.h index db5d3b9..759837c 100644 --- a/fit/decorate.h +++ b/fit/decorate.h @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include @@ -134,13 +134,13 @@ struct decoration } template -struct decorate_adaptor : F +struct decorate_adaptor : detail::callable_base { typedef decorate_adaptor fit_rewritable1_tag; - FIT_INHERIT_CONSTRUCTOR(decorate_adaptor, F) + FIT_INHERIT_CONSTRUCTOR(decorate_adaptor, detail::callable_base) template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -148,9 +148,9 @@ struct decorate_adaptor : F // TODO: Add predicate for constraints template - constexpr detail::decoration operator()(T x) const + constexpr detail::decoration> operator()(T x) const { - return detail::decoration(fit::move(x), this->base_function(x)); + return detail::decoration>(fit::move(x), this->base_function(x)); } }; diff --git a/fit/fix.h b/fit/fix.h index 5690d29..7ed6e17 100644 --- a/fit/fix.h +++ b/fit/fix.h @@ -48,7 +48,7 @@ /// #include -#include +#include #include #include #include @@ -71,12 +71,12 @@ namespace fit { namespace detail{ template -struct fix_adaptor_base : F +struct fix_adaptor_base : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(fix_adaptor_base, F); + FIT_INHERIT_CONSTRUCTOR(fix_adaptor_base, detail::callable_base); template - FIT_FIX_CONSTEXPR const F& base_function(Ts&&... xs) const + FIT_FIX_CONSTEXPR const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -100,17 +100,17 @@ struct fix_adaptor_base : F }; struct failure - : failure_map + : failure_map> {}; FIT_RETURNS_CLASS(fix_adaptor_base); template - FIT_FIX_CONSTEXPR FIT_SFINAE_RESULT(const F&, id_, id_...) + FIT_FIX_CONSTEXPR FIT_SFINAE_RESULT(const detail::callable_base&, id_, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( - FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)) + FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(xs...)) (FIT_MANGLE_CAST(const Derived&)(FIT_CONST_THIS->derived_function(xs...)), fit::forward(xs)...) ); }; diff --git a/fit/flip.h b/fit/flip.h index e32f0a4..679d6c2 100644 --- a/fit/flip.h +++ b/fit/flip.h @@ -42,7 +42,7 @@ /// assert(r == 3); /// -#include +#include #include #include #include @@ -50,10 +50,10 @@ namespace fit { template -struct flip_adaptor : F +struct flip_adaptor : detail::callable_base { typedef flip_adaptor fit_rewritable1_tag; - FIT_INHERIT_CONSTRUCTOR(flip_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(flip_adaptor, detail::callable_base); template constexpr const F& base_function(Ts&&... xs) const @@ -74,16 +74,16 @@ struct flip_adaptor : F }; struct failure - : failure_map + : failure_map> {}; FIT_RETURNS_CLASS(flip_adaptor); template - constexpr FIT_SFINAE_RESULT(const F&, id_, id_, id_...) + constexpr FIT_SFINAE_RESULT(const detail::callable_base&, id_, id_, id_...) operator()(T&& x, U&& y, Ts&&... xs) const FIT_SFINAE_RETURNS ( - (FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...))) + (FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(xs...))) (fit::forward(y), fit::forward(x), fit::forward(xs)...) ); }; diff --git a/fit/flow.h b/fit/flow.h index 5641397..2822227 100644 --- a/fit/flow.h +++ b/fit/flow.h @@ -64,7 +64,7 @@ /// assert(r == 4); /// -#include +#include #include #include #include @@ -77,20 +77,20 @@ namespace fit { namespace detail { template -struct flow_kernel : detail::compressed_pair +struct flow_kernel : detail::compressed_pair, detail::callable_base> { - typedef detail::compressed_pair base_type; + typedef detail::compressed_pair, detail::callable_base> base_type; FIT_INHERIT_CONSTRUCTOR(flow_kernel, base_type) FIT_RETURNS_CLASS(flow_kernel); template - constexpr FIT_SFINAE_RESULT(const F2&, result_of...>) + constexpr FIT_SFINAE_RESULT(const detail::callable_base&, result_of&, id_...>) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( - FIT_MANGLE_CAST(const F2&)(FIT_CONST_THIS->second(xs...))( - FIT_MANGLE_CAST(const F1&)(FIT_CONST_THIS->first(xs...))(fit::forward(xs)...) + FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->second(xs...))( + FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->first(xs...))(fit::forward(xs)...) ) ); }; @@ -112,14 +112,14 @@ struct flow_adaptor : detail::flow_kernel }; template -struct flow_adaptor : F +struct flow_adaptor : detail::callable_base { typedef flow_adaptor fit_rewritable_tag; - FIT_INHERIT_DEFAULT(flow_adaptor, F) + FIT_INHERIT_DEFAULT(flow_adaptor, detail::callable_base) - template + template)> constexpr flow_adaptor(X&& f1) - : F(fit::forward(f1)) + : detail::callable_base(fit::forward(f1)) {} }; diff --git a/fit/if.h b/fit/if.h index 2689acd..3c81f5c 100644 --- a/fit/if.h +++ b/fit/if.h @@ -58,7 +58,7 @@ /// #include -#include +#include #include #include #include @@ -74,9 +74,9 @@ struct if_depend {}; template -struct if_adaptor : F +struct if_adaptor : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(if_adaptor, F) + FIT_INHERIT_CONSTRUCTOR(if_adaptor, detail::callable_base) }; template diff --git a/fit/indirect.h b/fit/indirect.h index 9dc82bf..0f4366b 100644 --- a/fit/indirect.h +++ b/fit/indirect.h @@ -61,7 +61,7 @@ #include namespace fit { - +// TODO: Support non-classes as well template struct indirect_adaptor : F { diff --git a/fit/infix.h b/fit/infix.h index 59e2347..4218776 100644 --- a/fit/infix.h +++ b/fit/infix.h @@ -55,7 +55,7 @@ /// #include -#include +#include #include #include #include @@ -105,19 +105,19 @@ constexpr postfix_adaptor make_postfix_adaptor(T&& x, F f) } template -struct infix_adaptor : F +struct infix_adaptor : detail::callable_base { typedef infix_adaptor fit_rewritable1_tag; - FIT_INHERIT_CONSTRUCTOR(infix_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(infix_adaptor, detail::callable_base); template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } template - constexpr const F& infix_base_function(Ts&&... xs) const + constexpr const detail::callable_base& infix_base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -127,7 +127,7 @@ struct infix_adaptor : F template constexpr auto operator()(Ts&&... xs) const FIT_RETURNS ( - (FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward(xs)...) + (FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(xs...)))(fit::forward(xs)...) ); }; diff --git a/fit/lazy.h b/fit/lazy.h index 855650a..09a9ffa 100644 --- a/fit/lazy.h +++ b/fit/lazy.h @@ -225,12 +225,12 @@ constexpr lazy_nullary_invoker make_lazy_nullary_invoker(F f) template -struct lazy_adaptor : F +struct lazy_adaptor : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(lazy_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(lazy_adaptor, detail::callable_base); template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -240,7 +240,7 @@ struct lazy_adaptor : F template constexpr auto operator()(T x, Ts... xs) const FIT_RETURNS ( - fit::detail::make_lazy_invoker(FIT_RETURNS_C_CAST(F&&)(FIT_CONST_THIS->base_function(x, xs...)), + fit::detail::make_lazy_invoker(FIT_RETURNS_C_CAST(detail::callable_base&&)(FIT_CONST_THIS->base_function(x, xs...)), pack(fit::move(x), fit::move(xs)...)) ); @@ -248,7 +248,7 @@ struct lazy_adaptor : F template constexpr detail::lazy_nullary_invoker operator()() const { - return fit::detail::make_lazy_nullary_invoker((F&&)( + return fit::detail::make_lazy_nullary_invoker((detail::callable_base&&)( this->base_function(Unused()) )); } diff --git a/fit/match.h b/fit/match.h index 0a19dd0..363e703 100644 --- a/fit/match.h +++ b/fit/match.h @@ -62,6 +62,7 @@ /// #include +#include #include #include #include @@ -72,20 +73,20 @@ namespace fit { template struct match_adaptor; template -struct match_adaptor : F, match_adaptor +struct match_adaptor : detail::callable_base, match_adaptor { typedef match_adaptor base; typedef match_adaptor fit_rewritable_tag; struct failure - : failure_for + : failure_for, Fs...> {}; - FIT_INHERIT_DEFAULT(match_adaptor, F, base); + FIT_INHERIT_DEFAULT(match_adaptor, detail::callable_base, base); - template + template), FIT_ENABLE_IF_CONSTRUCTIBLE(base, Xs...)> constexpr match_adaptor(X&& f1, Xs&& ... fs) - : F(fit::forward(f1)), base(fit::forward(fs)...) + : detail::callable_base(fit::forward(f1)), base(fit::forward(fs)...) {} using F::operator(); @@ -93,13 +94,13 @@ struct match_adaptor : F, match_adaptor }; template -struct match_adaptor : F +struct match_adaptor : detail::callable_base { - typedef F base; + typedef detail::callable_base base; typedef match_adaptor fit_rewritable_tag; using F::operator(); - FIT_INHERIT_CONSTRUCTOR(match_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(match_adaptor, detail::callable_base); }; FIT_DECLARE_STATIC_VAR(match, detail::make); diff --git a/fit/protect.h b/fit/protect.h index 3cc09e8..641f3ac 100644 --- a/fit/protect.h +++ b/fit/protect.h @@ -44,11 +44,11 @@ namespace fit { template -struct protect_adaptor : F +struct protect_adaptor : detail::callable_base { typedef protect_adaptor fit_rewritable1_tag; template - constexpr protect_adaptor(Ts&&... xs) : F(fit::forward(xs)...) + constexpr protect_adaptor(Ts&&... xs) : detail::callable_base(fit::forward(xs)...) {} }; diff --git a/fit/result.h b/fit/result.h index 3a0cdad..b581c72 100644 --- a/fit/result.h +++ b/fit/result.h @@ -50,7 +50,7 @@ /// static_assert(std::is_same::value, "Not the same type"); /// -#include +#include #include #include #include @@ -58,18 +58,18 @@ namespace fit { template -struct result_adaptor : F +struct result_adaptor : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(result_adaptor, F) + FIT_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base) typedef Result result_type; struct failure - : failure_for + : failure_for> {}; template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -82,14 +82,14 @@ struct result_adaptor : F }; template -struct result_adaptor : F +struct result_adaptor : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(result_adaptor, F) + FIT_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base) typedef void result_type; template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } diff --git a/fit/reveal.h b/fit/reveal.h index b8b180d..faf57ba 100644 --- a/fit/reveal.h +++ b/fit/reveal.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -211,13 +212,13 @@ struct failure_for template struct reveal_adaptor -: detail::traverse_failure, F +: detail::traverse_failure>, detail::callable_base { typedef reveal_adaptor fit_rewritable1_tag; - using detail::traverse_failure::operator(); - using F::operator(); + using detail::traverse_failure>::operator(); + using detail::callable_base::operator(); - FIT_INHERIT_CONSTRUCTOR(reveal_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(reveal_adaptor, detail::callable_base); }; // Avoid double reveals, it causes problem on gcc 4.6 template diff --git a/fit/reverse_compress.h b/fit/reverse_compress.h index 40e93d9..9c5c4eb 100644 --- a/fit/reverse_compress.h +++ b/fit/reverse_compress.h @@ -66,7 +66,7 @@ /// assert(fit::reverse_compress(max_f())(2, 3, 4, 5) == 5); /// -#include +#include #include #include #include @@ -96,13 +96,13 @@ struct v_reverse_fold template struct reverse_compress_adaptor -: detail::compressed_pair +: detail::compressed_pair, State> { - typedef detail::compressed_pair base_type; + typedef detail::compressed_pair, State> base_type; FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, base_type) template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return this->first(xs...); } @@ -114,11 +114,11 @@ struct reverse_compress_adaptor } template - constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_, id_, id_...) + constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_&>, id_, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::v_reverse_fold()( - FIT_MANGLE_CAST(const F&)(this->base_function(xs...)), + FIT_MANGLE_CAST(const detail::callable_base&)(this->base_function(xs...)), FIT_MANGLE_CAST(State)(this->get_state(xs...)), fit::forward(xs)... ) @@ -128,22 +128,22 @@ struct reverse_compress_adaptor template struct reverse_compress_adaptor -: F +: detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, F) + FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, detail::callable_base) template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } template - constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_, id_...) + constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_&>, id_...) operator()(Ts&&... xs) const FIT_SFINAE_RETURNS ( detail::v_reverse_fold()( - FIT_MANGLE_CAST(const F&)(this->base_function(xs...)), + FIT_MANGLE_CAST(const detail::callable_base&)(this->base_function(xs...)), fit::forward(xs)... ) ) diff --git a/fit/rotate.h b/fit/rotate.h index 4134a05..0a4b5b2 100644 --- a/fit/rotate.h +++ b/fit/rotate.h @@ -51,13 +51,13 @@ namespace fit { template -struct rotate_adaptor : F +struct rotate_adaptor : detail::callable_base { typedef rotate_adaptor fit_rewritable1_tag; - FIT_INHERIT_CONSTRUCTOR(rotate_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(rotate_adaptor, detail::callable_base); template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -75,16 +75,16 @@ struct rotate_adaptor : F }; struct failure - : failure_map + : failure_map> {}; FIT_RETURNS_CLASS(rotate_adaptor); template - constexpr FIT_SFINAE_RESULT(const F&, id_..., id_) + constexpr FIT_SFINAE_RESULT(const detail::callable_base&, id_..., id_) operator()(T&& x, Ts&&... xs) const FIT_SFINAE_RETURNS ( - (FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(xs...))) + (FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(xs...))) (fit::forward(xs)..., fit::forward(x)) ); }; diff --git a/fit/tap.h b/fit/tap.h index 315e69c..86f04df 100644 --- a/fit/tap.h +++ b/fit/tap.h @@ -51,6 +51,7 @@ /// #include +#include #include namespace fit { namespace detail { @@ -60,7 +61,7 @@ struct tap_f template constexpr T operator()(T&& x, const F& f) const { - return f(x), fit::forward(x); + return fit::apply(f, x), fit::forward(x); } }; diff --git a/fit/unpack.h b/fit/unpack.h index b362b21..433cc7e 100644 --- a/fit/unpack.h +++ b/fit/unpack.h @@ -172,13 +172,13 @@ struct is_unpackable {}; template -struct unpack_adaptor : F +struct unpack_adaptor : detail::callable_base { typedef unpack_adaptor fit_rewritable1_tag; - FIT_INHERIT_CONSTRUCTOR(unpack_adaptor, F); + FIT_INHERIT_CONSTRUCTOR(unpack_adaptor, detail::callable_base); template - constexpr const F& base_function(Ts&&... xs) const + constexpr const detail::callable_base& base_function(Ts&&... xs) const { return always_ref(*this)(xs...); } @@ -223,7 +223,7 @@ struct unpack_adaptor : F }; struct failure - : failure_map + : failure_map> {}; FIT_RETURNS_CLASS(unpack_adaptor); @@ -233,7 +233,7 @@ struct unpack_adaptor : F constexpr auto operator()(T&& x) const FIT_RETURNS ( - detail::unpack_simple(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(x)), fit::forward(x)) + detail::unpack_simple(FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(x)), fit::forward(x)) ); template::value)>::type> constexpr auto operator()(T&& x, Ts&&... xs) const FIT_RETURNS ( - detail::unpack_join(FIT_MANGLE_CAST(const F&)(FIT_CONST_THIS->base_function(x)), fit::forward(x), fit::forward(xs)...) + detail::unpack_join(FIT_MANGLE_CAST(const detail::callable_base&)(FIT_CONST_THIS->base_function(x)), fit::forward(x), fit::forward(xs)...) ); }; From 761aa37c87eb25cdf32c869eacdfa79aff3a8171 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 26 Nov 2015 11:47:26 -0500 Subject: [PATCH 12/17] Make decorators use callable --- fit/decorate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fit/decorate.h b/fit/decorate.h index 759837c..cffe015 100644 --- a/fit/decorate.h +++ b/fit/decorate.h @@ -125,9 +125,9 @@ struct decoration } template - constexpr decorator_invoke operator()(F f) const + constexpr decorator_invoke, T, D> operator()(F f) const { - return decorator_invoke(fit::move(f), this->get_data(f), this->get_decorator(f)); + return decorator_invoke, T, D>(fit::move(f), this->get_data(f), this->get_decorator(f)); } }; From e205bda314a0f17d9105b4745968503f6fb37ce8 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 26 Nov 2015 11:58:07 -0500 Subject: [PATCH 13/17] Add callable to pipable and partial --- fit/partial.h | 14 +++++++------- fit/pipable.h | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fit/partial.h b/fit/partial.h index 611de5b..6f70c67 100644 --- a/fit/partial.h +++ b/fit/partial.h @@ -186,14 +186,14 @@ struct partial_adaptor_base } template -struct partial_adaptor : detail::partial_adaptor_base::type, F, Pack +struct partial_adaptor : detail::partial_adaptor_base, Pack>::type, detail::callable_base, Pack { - typedef typename detail::partial_adaptor_base::type base; + typedef typename detail::partial_adaptor_base, Pack>::type base; typedef partial_adaptor fit_rewritable1_tag; template - constexpr const F& base_function(Ts&&...) const + constexpr const detail::callable_base& base_function(Ts&&...) const { return *this; } @@ -209,19 +209,19 @@ struct partial_adaptor : detail::partial_adaptor_base::type, F, Pack {} template - constexpr partial_adaptor(X&& x, S&& seq) : F(fit::forward(x)), Pack(fit::forward(seq)) + constexpr partial_adaptor(X&& x, S&& seq) : detail::callable_base(fit::forward(x)), Pack(fit::forward(seq)) {} }; template -struct partial_adaptor : detail::partial_adaptor_base::type +struct partial_adaptor : detail::partial_adaptor_base, void>::type { - typedef typename detail::partial_adaptor_base::type base; + typedef typename detail::partial_adaptor_base, void>::type base; typedef partial_adaptor fit_rewritable1_tag; template - constexpr const F& base_function(Ts&&...) const + constexpr const detail::callable_base& base_function(Ts&&...) const { return *this; } diff --git a/fit/pipable.h b/fit/pipable.h index 30c3c6b..148a422 100644 --- a/fit/pipable.h +++ b/fit/pipable.h @@ -145,14 +145,14 @@ constexpr auto operator|(A&& a, const pipe_closure& p) FIT_RETURNS template struct pipable_adaptor -: conditional_adaptor, F> > +: conditional_adaptor, detail::pipe_pack, detail::callable_base> > { - typedef conditional_adaptor, F> > base; + typedef conditional_adaptor, detail::pipe_pack, detail::callable_base> > base; typedef pipable_adaptor fit_rewritable_tag; FIT_INHERIT_CONSTRUCTOR(pipable_adaptor, base); - constexpr const F& base_function() const + constexpr const detail::callable_base& base_function() const { return *this; } From b20febce314b26a97c3e482c2f6f9c7f1b3660b9 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 26 Nov 2015 12:00:29 -0500 Subject: [PATCH 14/17] Add callable to is_callable --- fit/is_callable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fit/is_callable.h b/fit/is_callable.h index 1fd6b7b..6e4edcb 100644 --- a/fit/is_callable.h +++ b/fit/is_callable.h @@ -38,12 +38,13 @@ #include +#include namespace fit { template struct is_callable -: detail::can_be_called +: detail::can_be_called {}; } From 59d31b5362814f2b7ab7ffa4a7cdc8126f30ff67 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 15 Dec 2015 18:11:48 -0600 Subject: [PATCH 15/17] Fix typo --- fit/detail/callable_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fit/detail/callable_base.h b/fit/detail/callable_base.h index 4e35c2f..00f6e27 100644 --- a/fit/detail/callable_base.h +++ b/fit/detail/callable_base.h @@ -44,7 +44,7 @@ template::value) struct callable_base : Base { - FIT_INHERIT_CONSTRUCTOR(callable_basse, Base) + FIT_INHERIT_CONSTRUCTOR(callable_base, Base) }; #endif From b805238c7cd3754f2acaf3995ee6d22cc4327fc0 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 17 Dec 2015 00:01:45 -0600 Subject: [PATCH 16/17] Prevent recursive instantiations of callable base in partial --- fit/detail/callable_base.h | 22 +++++++++++++++++++--- fit/partial.h | 19 ++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/fit/detail/callable_base.h b/fit/detail/callable_base.h index 00f6e27..d362b64 100644 --- a/fit/detail/callable_base.h +++ b/fit/detail/callable_base.h @@ -40,12 +40,28 @@ struct non_class_function template using callable_base = typename std::conditional<(std::is_class::value), F, non_class_function>::type; #else -template::value), F, non_class_function>::type> + +template +struct callable_base_type +: std::conditional<(std::is_class::value), F, non_class_function> +{}; + +template struct callable_base -: Base +: callable_base_type::type { - FIT_INHERIT_CONSTRUCTOR(callable_base, Base) + typedef typename callable_base_type::type base; + FIT_INHERIT_CONSTRUCTOR(callable_base, base) }; + +template +struct callable_base> +: callable_base +{ + typedef callable_base base; + FIT_INHERIT_CONSTRUCTOR(callable_base, base) +}; + #endif }} diff --git a/fit/partial.h b/fit/partial.h index 6f70c67..660d26b 100644 --- a/fit/partial.h +++ b/fit/partial.h @@ -173,27 +173,27 @@ struct partial_adaptor_base > type; }; -template -struct partial_adaptor_base +template +struct partial_adaptor_pack_base { typedef conditional_adaptor < F, - partial_adaptor_pack, F> + partial_adaptor_pack > type; }; } template -struct partial_adaptor : detail::partial_adaptor_base, Pack>::type, detail::callable_base, Pack +struct partial_adaptor : detail::partial_adaptor_base::type, F, Pack { - typedef typename detail::partial_adaptor_base, Pack>::type base; + typedef typename detail::partial_adaptor_base::type base; typedef partial_adaptor fit_rewritable1_tag; template - constexpr const detail::callable_base& base_function(Ts&&...) const + constexpr const F& base_function(Ts&&...) const { return *this; } @@ -209,14 +209,14 @@ struct partial_adaptor : detail::partial_adaptor_base, {} template - constexpr partial_adaptor(X&& x, S&& seq) : detail::callable_base(fit::forward(x)), Pack(fit::forward(seq)) + constexpr partial_adaptor(X&& x, S&& seq) : F(fit::forward(x)), Pack(fit::forward(seq)) {} }; template -struct partial_adaptor : detail::partial_adaptor_base, void>::type +struct partial_adaptor : detail::partial_adaptor_pack_base, detail::callable_base>::type { - typedef typename detail::partial_adaptor_base, void>::type base; + typedef typename detail::partial_adaptor_pack_base, detail::callable_base>::type base; typedef partial_adaptor fit_rewritable1_tag; @@ -231,6 +231,7 @@ struct partial_adaptor : detail::partial_adaptor_base struct partial_adaptor, void> From 3454a17c663ca507b68e88deedc6dd314745aeac Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 17 Dec 2015 13:04:50 -0600 Subject: [PATCH 17/17] Add documentation for callable --- doc/src/concepts.md | 73 ++++++++++++++++++++++++++++++++++++++++++ fit/apply.h | 2 +- fit/apply_eval.h | 2 +- fit/by.h | 6 ++-- fit/combine.h | 2 +- fit/compose.h | 2 +- fit/compress.h | 2 +- fit/conditional.h | 2 +- fit/decorate.h | 2 +- fit/fix.h | 2 +- fit/flip.h | 2 +- fit/flow.h | 2 +- fit/if.h | 2 +- fit/infix.h | 2 +- fit/is_callable.h | 8 ++++- fit/lazy.h | 2 +- fit/match.h | 2 +- fit/partial.h | 2 +- fit/pipable.h | 2 +- fit/protect.h | 2 +- fit/result.h | 2 +- fit/reveal.h | 2 +- fit/reverse_compress.h | 2 +- fit/rotate.h | 2 +- fit/tap.h | 2 +- fit/unpack.h | 2 +- 26 files changed, 106 insertions(+), 27 deletions(-) diff --git a/doc/src/concepts.md b/doc/src/concepts.md index 2314b0e..1b27ac7 100644 --- a/doc/src/concepts.md +++ b/doc/src/concepts.md @@ -165,6 +165,79 @@ Given |---------------|--------------------------| | `f(identity)` | performs a function call | +Callable +-------- + +Is an object for which the `INVOKE` operation can be applied. + +#### Requirements: + +The type `T` satisfies `Callable` if + +Given + +* `f`, an object of type `const T` +* `Args...`, suitable list of argument types + +The following expressions must be valid: + +| Expression | Requirements | +|--------------------------------------|-------------------------------------------------------| +| `INVOKE(f, std::declval()...)` | the expression is well-formed in unevaluated context | + +where `INVOKE(f, x, xs...)` is defined as follows: + +* if `f` is a pointer to member function of class `T`: + + - If `std::is_base_of>()` is true, then `INVOKE(f, x, xs...)` is equivalent to `(x.*f)(xs...)` + - otherwise, if `std::decay_t` is a specialization of `std::reference_wrapper`, then `INVOKE(f, x, xs...)` is equivalent to `(x.get().*f)(xs...)` + - otherwise, if x does not satisfy the previous items, then `INVOKE(f, x, xs...)` is equivalent to `((*x).*f)(xs...)`. + +* otherwise, if `f` is a pointer to data member of class `T`: + + - If `std::is_base_of>()` is true, then `INVOKE(f, x)` is equivalent to `x.*f` + - otherwise, if `std::decay_t` is a specialization of `std::reference_wrapper`, then `INVOKE(f, x)` is equivalent to `x.get().*f` + - otherwise, if `x` does not satisfy the previous items, then `INVOKE(f, x)` is equivalent to `(*x).*f` + +* otherwise, `INVOKE(f, x, xs...)` is equivalent to `f(x, xs...)` + +UnaryCallable +------------- + +Is an object for which the `INVOKE` operation can be applied with one parameter. + +#### Requirements: + +* `Callable` + +Given + +* `f`, an object of type `const F` +* `arg`, a single argument + +| Expression | Requirements | +|------------------|-------------------------------------------------------| +| `INVOKE(f, arg)` | the expression is well-formed in unevaluated context | + +BinaryCallable +-------------------- + +Is an object for which the `INVOKE` operation can be applied with two parameters. + +#### Requirements: + +* `Callable` + +Given + +* `f`, an object of type `const F` +* `arg1`, a single argument +* `arg2`, a single argument + +| Expression | Requirements | +|-------------------------|-------------------------------------------------------| +| `INVOKE(f, arg1, arg2)` | the expression is well-formed in unevaluated context | + Metafunction ------------ diff --git a/fit/apply.h b/fit/apply.h index 99673ea..d45e70d 100644 --- a/fit/apply.h +++ b/fit/apply.h @@ -32,7 +32,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// /// Example /// ------- diff --git a/fit/apply_eval.h b/fit/apply_eval.h index ae613bb..6395782 100644 --- a/fit/apply_eval.h +++ b/fit/apply_eval.h @@ -34,7 +34,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// /// Ts must be: /// diff --git a/fit/by.h b/fit/by.h index d7f65c9..91f845c 100644 --- a/fit/by.h +++ b/fit/by.h @@ -43,12 +43,12 @@ /// /// Projection must be: /// -/// * [UnaryFunctionObject](concepts.md#unaryfunctionobject) +/// * [UnaryCallable](concepts.md#unarycallable) /// * MoveConstructible /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example @@ -60,7 +60,7 @@ /// {} /// int x; /// }; -/// assert(fit::by(std::mem_fn(&foo::x), _ + _)(foo(1), foo(2)) == 3); +/// assert(fit::by(&foo::x, _ + _)(foo(1), foo(2)) == 3); /// diff --git a/fit/combine.h b/fit/combine.h index 0ad68db..decc004 100644 --- a/fit/combine.h +++ b/fit/combine.h @@ -34,7 +34,7 @@ /// /// F and Gs must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/compose.h b/fit/compose.h index 11078b8..99380b3 100644 --- a/fit/compose.h +++ b/fit/compose.h @@ -36,7 +36,7 @@ /// /// Fs must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/compress.h b/fit/compress.h index 15c3202..cc5d94e 100644 --- a/fit/compress.h +++ b/fit/compress.h @@ -48,7 +48,7 @@ /// /// F must be: /// -/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject) +/// * [BinaryCallable](concepts.md#binarycallable) /// * MoveConstructible /// /// Example diff --git a/fit/conditional.h b/fit/conditional.h index f8018fa..19ed67a 100644 --- a/fit/conditional.h +++ b/fit/conditional.h @@ -35,7 +35,7 @@ /// /// Fs must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/decorate.h b/fit/decorate.h index cffe015..93bfe4d 100644 --- a/fit/decorate.h +++ b/fit/decorate.h @@ -32,7 +32,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// diff --git a/fit/fix.h b/fit/fix.h index 7ed6e17..93a9048 100644 --- a/fit/fix.h +++ b/fit/fix.h @@ -37,7 +37,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/flip.h b/fit/flip.h index 679d6c2..104bc13 100644 --- a/fit/flip.h +++ b/fit/flip.h @@ -32,7 +32,7 @@ /// /// F must be: /// -/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject) +/// * [BinaryCallable](concepts.md#binarycallable) /// * MoveConstructible /// /// Example diff --git a/fit/flow.h b/fit/flow.h index 2822227..63899c5 100644 --- a/fit/flow.h +++ b/fit/flow.h @@ -36,7 +36,7 @@ /// /// Fs must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/if.h b/fit/if.h index 3c81f5c..7785174 100644 --- a/fit/if.h +++ b/fit/if.h @@ -36,7 +36,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/infix.h b/fit/infix.h index 4218776..d4b439a 100644 --- a/fit/infix.h +++ b/fit/infix.h @@ -34,7 +34,7 @@ /// /// F must be: /// -/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject) +/// * [BinaryCallable](concepts.md#binarycallable) /// * MoveConstructible /// /// Example diff --git a/fit/is_callable.h b/fit/is_callable.h index 6e4edcb..86bbea9 100644 --- a/fit/is_callable.h +++ b/fit/is_callable.h @@ -14,9 +14,15 @@ /// Description /// ----------- /// -/// The `is_callable` metafunction checks if the function object is callable with +/// The `is_callable` metafunction checks if the function is callable with /// certain parameters. /// +/// Requirements +/// ------------ +/// +/// F must be: +/// +/// * [Callable](concepts.md#callable) /// /// Synopsis /// -------- diff --git a/fit/lazy.h b/fit/lazy.h index 09a9ffa..b098381 100644 --- a/fit/lazy.h +++ b/fit/lazy.h @@ -36,7 +36,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/match.h b/fit/match.h index 363e703..64d8f58 100644 --- a/fit/match.h +++ b/fit/match.h @@ -30,7 +30,7 @@ /// /// Fs must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/partial.h b/fit/partial.h index 660d26b..fd83d05 100644 --- a/fit/partial.h +++ b/fit/partial.h @@ -37,7 +37,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/pipable.h b/fit/pipable.h index 148a422..d0e0ebe 100644 --- a/fit/pipable.h +++ b/fit/pipable.h @@ -36,7 +36,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/protect.h b/fit/protect.h index 641f3ac..1b8486b 100644 --- a/fit/protect.h +++ b/fit/protect.h @@ -31,7 +31,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// diff --git a/fit/result.h b/fit/result.h index b581c72..d629e0d 100644 --- a/fit/result.h +++ b/fit/result.h @@ -31,7 +31,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/reveal.h b/fit/reveal.h index faf57ba..e0b175d 100644 --- a/fit/reveal.h +++ b/fit/reveal.h @@ -32,7 +32,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// diff --git a/fit/reverse_compress.h b/fit/reverse_compress.h index 9c5c4eb..897429b 100644 --- a/fit/reverse_compress.h +++ b/fit/reverse_compress.h @@ -49,7 +49,7 @@ /// /// F must be: /// -/// * [BinaryFunctionObject](concepts.md#binaryfunctionobject) +/// * [BinaryCallable](concepts.md#binarycallable) /// * MoveConstructible /// /// Example diff --git a/fit/rotate.h b/fit/rotate.h index 0a4b5b2..bf135c6 100644 --- a/fit/rotate.h +++ b/fit/rotate.h @@ -33,7 +33,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example diff --git a/fit/tap.h b/fit/tap.h index 86f04df..8f1355a 100644 --- a/fit/tap.h +++ b/fit/tap.h @@ -30,7 +30,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [UnaryCallable](concepts.md#unarycallable) /// /// Example /// ------- diff --git a/fit/unpack.h b/fit/unpack.h index 433cc7e..2b92c59 100644 --- a/fit/unpack.h +++ b/fit/unpack.h @@ -31,7 +31,7 @@ /// /// F must be: /// -/// * [FunctionObject](concepts.md#functionobject) +/// * [Callable](concepts.md#callable) /// * MoveConstructible /// /// Example