123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*=============================================================================
- Copyright (c) 2017 Paul Fultz II
- proj.cpp
- 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)
- ==============================================================================*/
- #include <boost/hof/proj.hpp>
- #include <boost/hof/placeholders.hpp>
- #include <boost/hof/mutable.hpp>
- #include "test.hpp"
- #include <memory>
- struct foo
- {
- constexpr foo(int xp) : x(xp)
- {}
- int x;
- };
- struct select_x
- {
- template<class T>
- constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS(x.x);
- };
- BOOST_HOF_TEST_CASE()
- {
- #ifndef _MSC_VER
- constexpr
- #endif
- auto add = boost::hof::_ + boost::hof::_;
- BOOST_HOF_STATIC_TEST_CHECK(boost::hof::proj(select_x(), add)(foo(1), foo(2)) == 3);
- // Using mutable_ as a workaround on libc++, since mem_fn does not meet the
- // requirements of a FunctionObject
- BOOST_HOF_TEST_CHECK(boost::hof::proj(boost::hof::mutable_(std::mem_fn(&foo::x)), add)(foo(1), foo(2)) == 3);
- static_assert(boost::hof::detail::is_default_constructible<decltype(boost::hof::proj(select_x(), add))>::value, "Not default constructible");
- }
- BOOST_HOF_TEST_CASE()
- {
- #ifndef _MSC_VER
- constexpr
- #endif
- auto add = boost::hof::_ + boost::hof::_;
- BOOST_HOF_STATIC_TEST_CHECK(boost::hof::proj(select_x(), add)(foo(1), foo(2)) == 3);
- BOOST_HOF_TEST_CHECK(boost::hof::proj(&foo::x, add)(foo(1), foo(2)) == 3);
- static_assert(boost::hof::detail::is_default_constructible<decltype(boost::hof::proj(select_x(), add))>::value, "Not default constructible");
- }
- BOOST_HOF_TEST_CASE()
- {
- auto indirect_add = boost::hof::proj(*boost::hof::_, boost::hof::_ + boost::hof::_);
- BOOST_HOF_TEST_CHECK(indirect_add(std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2))) == 3);
- static_assert(boost::hof::detail::is_default_constructible<decltype(indirect_add)>::value, "Not default constructible");
- }
- struct select_x_1
- {
- std::unique_ptr<int> i;
- select_x_1() : i(new int(2))
- {}
- template<class T>
- auto operator()(T&& x) const BOOST_HOF_RETURNS(x.x * (*i));
- };
- struct sum_1
- {
- std::unique_ptr<int> i;
- sum_1() : i(new int(1))
- {}
- template<class T, class U>
- auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS(x + y + *i);
- };
- BOOST_HOF_TEST_CASE()
- {
- BOOST_HOF_TEST_CHECK(boost::hof::proj(select_x_1(), sum_1())(foo(1), foo(2)) == 7);
- }
- BOOST_HOF_TEST_CASE()
- {
- std::string s;
- auto f = [&](const std::string& x)
- {
- s += x;
- };
- boost::hof::proj(f)("hello", "-", "world");
- BOOST_HOF_TEST_CHECK(s == "hello-world");
- boost::hof::proj(f)();
- BOOST_HOF_TEST_CHECK(s == "hello-world");
- }
- BOOST_HOF_TEST_CASE()
- {
- std::string s;
- auto f = [&](const std::string& x)
- {
- s += x;
- return s;
- };
- auto last = [](const std::string& x, const std::string& y, const std::string& z)
- {
- BOOST_HOF_TEST_CHECK(x == "hello");
- BOOST_HOF_TEST_CHECK(y == "hello-");
- BOOST_HOF_TEST_CHECK(z == "hello-world");
- return z;
- };
- BOOST_HOF_TEST_CHECK(boost::hof::proj(f, last)("hello", "-", "world") == "hello-world");
- }
- template<bool B>
- struct bool_
- {
- static const bool value = B;
- };
- struct constexpr_check
- {
- template<class T>
- constexpr int operator()(T) const
- {
- static_assert(T::value, "Failed");
- return 0;
- }
- };
- struct constexpr_check_each
- {
- template<class T>
- constexpr bool operator()(T x) const
- {
- return boost::hof::proj(constexpr_check())(x, x), true;
- }
- };
- BOOST_HOF_TEST_CASE()
- {
- BOOST_HOF_STATIC_TEST_CHECK(constexpr_check_each()(bool_<true>()));
- }
- BOOST_HOF_TEST_CASE()
- {
- boost::hof::proj(boost::hof::identity, boost::hof::identity)(0);
- }
- struct bar {};
- BOOST_HOF_TEST_CASE()
- {
- auto f = boost::hof::proj(bar{});
- static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly");
- static_assert(!boost::hof::is_invocable<decltype(f), int, int>::value, "Not sfinae friendly");
- static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not sfinae friendly");
- }
- BOOST_HOF_TEST_CASE()
- {
- auto f = boost::hof::proj(bar{}, bar{});
- static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly");
- static_assert(!boost::hof::is_invocable<decltype(f), int, int>::value, "Not sfinae friendly");
- static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not sfinae friendly");
- static_assert(!boost::hof::is_invocable<decltype(f)>::value, "Not sfinae friendly");
- }
|