From f3613f96a82c33eb970eda98b457c8a29577e19b Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 19 Jun 2015 23:43:42 -0400 Subject: [PATCH 1/3] Add if function --- CMakeLists.txt | 1 + fit/if.h | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ test/if.cpp | 59 +++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 fit/if.h create mode 100644 test/if.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4402651..8dbffc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ add_test_executable(flip) add_test_executable(flow) add_test_executable(function) add_test_executable(identity) +add_test_executable(if) add_test_executable(implicit) add_test_executable(indirect) add_test_executable(infix) diff --git a/fit/if.h b/fit/if.h new file mode 100644 index 0000000..c8700b6 --- /dev/null +++ b/fit/if.h @@ -0,0 +1,105 @@ +/*============================================================================= + Copyright (c) 2015 Paul Fultz II + if_.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_IF_H +#define FIT_GUARD_IF_H + +/// if +/// == +/// +/// Description +/// ----------- +/// +/// The `if_` function applies a boolen condition to the function. +/// +/// Synopsis +/// -------- +/// +/// template +/// constexpr auto if_(IntegralConstant); +/// +/// Requirements +/// ------------ +/// +/// IntegralConstant must be: +/// +/// IntegralConstant +/// +/// Example +/// ------- +/// +/// struct sum_f +/// { +/// template +/// T operator()(T x, U y) const +/// { +/// return x+y; +/// } +/// }; +/// assert(fit::if_(sum_f(), 1, 2) == 3); +/// + +#include +#include +#include +#include +#include +#include + +namespace fit { + +namespace detail { + +template +struct if_depend +: C +{}; + +template +struct if_adaptor : F +{ + FIT_INHERIT_CONSTRUCTOR(if_adaptor, F) +}; + +template +struct if_adaptor +{ + template + constexpr if_adaptor(Ts&&...) + {} +}; + +template +struct make_if_f +{ + constexpr make_if_f() + {} + template + constexpr if_adaptor operator()(F f) const + { + return if_adaptor(fit::move(f)); + } +}; + +struct if_f +{ + constexpr if_f() + {} + template + constexpr make_if_f operator()(Cond) const + { + return {}; + } +}; + +} + +FIT_DECLARE_STATIC_VAR(if_, detail::if_f); + +} + +#endif diff --git a/test/if.cpp b/test/if.cpp new file mode 100644 index 0000000..3fa4db9 --- /dev/null +++ b/test/if.cpp @@ -0,0 +1,59 @@ +#include +#include "test.h" + +#include + + +struct is_5 +{ + template + constexpr bool operator()(T i) const + { + return i == 5; + } +}; + +struct is_not_5 +{ + template + constexpr bool operator()(T i) const + { + return i != 5; + } +}; + +template +struct test_int +{ + template + constexpr bool operator()(T x) const + { + return fit::conditional( + fit::if_(std::is_integral())(F()), + fit::always(true) + )(x); + } +}; + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(test_int()(5)); + FIT_TEST_CHECK(test_int()(5L)); + FIT_TEST_CHECK(test_int()(5.0)); + FIT_TEST_CHECK(test_int()(6.0)); + + FIT_TEST_CHECK(test_int()(6)); + FIT_TEST_CHECK(test_int()(6L)); + FIT_TEST_CHECK(test_int()(5.0)); + FIT_TEST_CHECK(test_int()(6.0)); + + FIT_STATIC_TEST_CHECK(test_int()(5)); + FIT_STATIC_TEST_CHECK(test_int()(5L)); + FIT_STATIC_TEST_CHECK(test_int()(5.0)); + FIT_STATIC_TEST_CHECK(test_int()(6.0)); + + FIT_STATIC_TEST_CHECK(test_int()(6)); + FIT_STATIC_TEST_CHECK(test_int()(6L)); + FIT_STATIC_TEST_CHECK(test_int()(5.0)); + FIT_STATIC_TEST_CHECK(test_int()(6.0)); +} From dfa32f86e41d7d515f68b3393cbb1b55938b03cb Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 19 Jun 2015 23:52:00 -0400 Subject: [PATCH 2/3] Update test and doc --- fit/if.h | 12 ++++++++---- test/if.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/fit/if.h b/fit/if.h index c8700b6..4852c75 100644 --- a/fit/if.h +++ b/fit/if.h @@ -34,13 +34,17 @@ /// /// struct sum_f /// { -/// template -/// T operator()(T x, U y) const +/// template +/// int operator()(T x, T y) const /// { -/// return x+y; +/// return fit::conditional( +/// fit::if_(std::is_integral())(fit::_ + fit::_), +/// fit::always(0) +/// )(x, y); /// } /// }; -/// assert(fit::if_(sum_f(), 1, 2) == 3); +/// assert(sum_f()(1, 2) == 3); +/// assert(sum_f()("", "") == 0); /// #include diff --git a/test/if.cpp b/test/if.cpp index 3fa4db9..9788d25 100644 --- a/test/if.cpp +++ b/test/if.cpp @@ -2,6 +2,7 @@ #include "test.h" #include +#include struct is_5 @@ -57,3 +58,27 @@ FIT_TEST_CASE() FIT_STATIC_TEST_CHECK(test_int()(5.0)); FIT_STATIC_TEST_CHECK(test_int()(6.0)); } + +struct sum_f +{ + template + constexpr int operator()(T x, T y) const + { + return fit::conditional( + fit::if_(std::is_integral())(fit::_ + fit::_), + fit::always(0) + )(x, y); + } +}; + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(sum_f()(1, 2) == 3); + FIT_TEST_CHECK(sum_f()(1.0, 2.0) == 0); + FIT_TEST_CHECK(sum_f()("", "") == 0); + + FIT_STATIC_TEST_CHECK(sum_f()(1, 2) == 3); + FIT_STATIC_TEST_CHECK(sum_f()("", "") == 0); +} + + From 3a9b141284e35c0e6f3717770cb6c7a5738385ce Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 19 Jun 2015 23:57:03 -0400 Subject: [PATCH 3/3] Add if to the main docs --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 6494359..63b4e94 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -49,6 +49,7 @@ pages: - 'eval': 'eval.md' - 'FIT_STATIC_FUNCTION': 'function.md' - 'FIT_STATIC_LAMBDA': 'lambda.md' + - 'if': 'if.md' - 'lift': 'lift.md' - 'is_callable': 'is_callable.md' - 'pack': 'pack.md'