2
0
mirror of https://github.com/boostorg/hana.git synced 2026-01-24 05:52:14 +00:00

[Metafunction] Do not automatically call decltype_ on metafunction arguments

This commit is contained in:
Louis Dionne
2015-09-15 18:09:02 -04:00
parent f6f02ac748
commit b1696fe0cc
19 changed files with 44 additions and 212 deletions

View File

@@ -1245,8 +1245,9 @@ is what we must do:
@snippet example/tutorial/type.cpp single_library.then
With Hana, a single library is required (notice how we use the same `filter`
algorithm and the same container):
With Hana, a single library is required. Notice how we use the same `filter`
algorithm and the same container, and only tweak the predicate so it can
operate on values:
@snippet example/tutorial/type.cpp single_library.Hana

View File

@@ -13,16 +13,10 @@ namespace hana = boost::hana;
namespace mpl = boost::mpl;
auto xs = hana::make_tuple(1, '2', 3.0);
auto xs = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<double>);
static_assert(std::is_same<
decltype(hana::to<hana::ext::boost::mpl::list_tag>(xs)),
mpl::list<int, char, double>
>{}, "");
auto ys = hana::make_tuple(1, '2', hana::type_c<void>);
static_assert(std::is_same<
decltype(hana::to<hana::ext::boost::mpl::list_tag>(ys)),
mpl::list<int, char, void>
>{}, "");
int main() { }

View File

@@ -13,16 +13,10 @@ namespace hana = boost::hana;
namespace mpl = boost::mpl;
auto xs = hana::make_tuple(1, '2', 3.0);
auto xs = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<double>);
static_assert(std::is_same<
decltype(hana::to<hana::ext::boost::mpl::vector_tag>(xs)),
mpl::vector<int, char, double>
>{}, "");
auto ys = hana::make_tuple(1, '2', hana::type_c<void>);
static_assert(std::is_same<
decltype(hana::to<hana::ext::boost::mpl::vector_tag>(ys)),
mpl::vector<int, char, void>
>{}, "");
int main() { }

View File

@@ -6,6 +6,7 @@
#include <boost/hana/equal.hpp>
#include <boost/hana/ext/std/integral_constant.hpp>
#include <boost/hana/filter.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/type.hpp>
@@ -14,8 +15,11 @@
namespace hana = boost::hana;
static_assert(hana::filter(hana::make_tuple(1, 2.0, 3, 4.0), hana::trait<std::is_integral>) == hana::make_tuple(1, 3), "");
static_assert(hana::filter(hana::just(3), hana::trait<std::is_integral>) == hana::just(3), "");
BOOST_HANA_CONSTANT_CHECK(hana::filter(hana::just(3.0), hana::trait<std::is_integral>) == hana::nothing);
// First take the type of an object, and then tell whether it's integral
constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::decltype_);
static_assert(hana::filter(hana::make_tuple(1, 2.0, 3, 4.0), is_integral) == hana::make_tuple(1, 3), "");
static_assert(hana::filter(hana::just(3), is_integral) == hana::just(3), "");
BOOST_HANA_CONSTANT_CHECK(hana::filter(hana::just(3.0), is_integral) == hana::nothing);
int main() { }

View File

@@ -7,6 +7,7 @@
#include <boost/hana/equal.hpp>
#include <boost/hana/ext/std/integral_constant.hpp>
#include <boost/hana/find_if.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/type.hpp>
@@ -15,12 +16,16 @@
namespace hana = boost::hana;
// First get the type of the object, and then call the trait on it.
constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::decltype_);
constexpr auto is_class = hana::compose(hana::trait<std::is_class>, hana::decltype_);
static_assert(
hana::find_if(hana::make_tuple(1.0, 2, '3'), hana::trait<std::is_integral>) == hana::just(2)
hana::find_if(hana::make_tuple(1.0, 2, '3'), is_integral) == hana::just(2)
, "");
BOOST_HANA_CONSTANT_CHECK(
hana::find_if(hana::make_tuple(1.0, 2, '3'), hana::trait<std::is_class>) == hana::nothing
hana::find_if(hana::make_tuple(1.0, 2, '3'), is_class) == hana::nothing
);
constexpr auto types = hana::tuple_t<char, int, unsigned, long, unsigned long>;

View File

@@ -6,6 +6,7 @@
#include <boost/hana/ext/std/integral_constant.hpp>
#include <boost/hana/find.hpp>
#include <boost/hana/find_if.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/tuple.hpp>
@@ -15,15 +16,18 @@
namespace hana = boost::hana;
// First get the type of the object, and then call the trait on it.
constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::decltype_);
constexpr auto is_class = hana::compose(hana::trait<std::is_class>, hana::decltype_);
static_assert(
hana::find_if(hana::make_tuple(1.0, 2, '3'), hana::trait<std::is_integral>)
hana::find_if(hana::make_tuple(1.0, 2, '3'), is_integral)
==
hana::just(2)
, "");
BOOST_HANA_CONSTANT_CHECK(
hana::find_if(hana::make_tuple(1.0, 2, '3'), hana::trait<std::is_class>)
hana::find_if(hana::make_tuple(1.0, 2, '3'), is_class)
==
hana::nothing
);

View File

@@ -5,6 +5,7 @@
#include <boost/hana/assert.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/ext/std/integral_constant.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/remove_if.hpp>
#include <boost/hana/tuple.hpp>
@@ -14,8 +15,11 @@
namespace hana = boost::hana;
static_assert(hana::remove_if(hana::make_tuple(1, 2.0, 3, 4.0), hana::trait<std::is_integral>) == hana::make_tuple(2.0, 4.0), "");
static_assert(hana::remove_if(hana::just(3.0), hana::trait<std::is_integral>) == hana::just(3.0), "");
BOOST_HANA_CONSTANT_CHECK(hana::remove_if(hana::just(3), hana::trait<std::is_integral>) == hana::nothing);
// First get the type of the object, and then call the trait on it.
constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::decltype_);
static_assert(hana::remove_if(hana::make_tuple(1, 2.0, 3, 4.0), is_integral) == hana::make_tuple(2.0, 4.0), "");
static_assert(hana::remove_if(hana::just(3.0), is_integral) == hana::just(3.0), "");
BOOST_HANA_CONSTANT_CHECK(hana::remove_if(hana::just(3), is_integral) == hana::nothing);
int main() { }

View File

@@ -22,7 +22,7 @@ int main() {
auto tuple = hana::make_tuple(1, 'x', 3.4f);
auto result = hana::find_if(tuple, [](auto const& x) {
return hana::traits::is_integral(x);
return hana::traits::is_integral(hana::decltype_(x));
});
//! [hana]
(void)result;
@@ -30,7 +30,7 @@ auto result = hana::find_if(tuple, [](auto const& x) {
#if 0
//! [hana-explicit]
some_type result = hana::find_if(tuple, [](auto const& x) {
return hana::traits::is_integral(x);
return hana::traits::is_integral(hana::decltype_(x));
});
//! [hana-explicit]
#endif

View File

@@ -101,8 +101,8 @@ auto ts = hana::filter(types, [](auto t) {
// values
auto values = hana::make_tuple(1, 'c', nullptr, 3.5);
auto vs = hana::filter(values, [](auto t) {
return is_integral(t);
auto vs = hana::filter(values, [](auto const& t) {
return is_integral(hana::decltype_(t));
});
//! [single_library.Hana]

View File

@@ -18,9 +18,6 @@ BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>() == hana::type_c<f<>::type>);
BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>(hana::type_c<x>) == hana::type_c<f<x>::type>);
BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>(hana::type_c<x>, hana::type_c<y>) == hana::type_c<f<x, y>::type>);
// calling `metafunction` on non-types
BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>(1) == hana::type_c<f<int>::type>);
static_assert(std::is_same<
decltype(hana::metafunction<f>)::apply<x, y>::type,
f<x, y>::type

View File

@@ -18,9 +18,6 @@ BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>() == hana::type_c<f::apply
BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>(hana::type_c<x>) == hana::type_c<f::apply<x>::type>);
BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>(hana::type_c<x>, hana::type_c<y>) == hana::type_c<f::apply<x, y>::type>);
// calling `hana::metafunction_class` on non-types
BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>(1) == hana::type_c<f::apply<int>::type>);
static_assert(std::is_same<
decltype(hana::metafunction_class<f>)::apply<x, y>::type,
f::apply<x, y>::type

View File

@@ -18,9 +18,6 @@ BOOST_HANA_CONSTANT_CHECK(hana::template_<f>() == hana::type_c<f<>>);
BOOST_HANA_CONSTANT_CHECK(hana::template_<f>(hana::type_c<x>) == hana::type_c<f<x>>);
BOOST_HANA_CONSTANT_CHECK(hana::template_<f>(hana::type_c<x>, hana::type_c<y>) == hana::type_c<f<x, y>>);
// calling `hana::template_` on non-types
BOOST_HANA_CONSTANT_CHECK(hana::template_<f>(1) == hana::type_c<f<int>>);
static_assert(std::is_same<
decltype(hana::template_<f>)::apply<x, y>::type,
f<x, y>

View File

@@ -175,9 +175,8 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename F>
struct to_impl<ext::boost::mpl::vector_tag, F, when<hana::Foldable<F>::value>> {
template <typename Xs>
static constexpr decltype(auto) apply(Xs&& xs) {
auto vector_type = hana::unpack(static_cast<Xs&&>(xs),
hana::template_<::boost::mpl::vector>);
static constexpr auto apply(Xs const& xs) {
auto vector_type = hana::unpack(xs, hana::template_<boost::mpl::vector>);
return typename decltype(vector_type)::type{};
}
};

View File

@@ -137,8 +137,8 @@ BOOST_HANA_NAMESPACE_BEGIN
};
template <typename ...T>
constexpr auto operator()(T&& ...) const
{ return hana::type_c<F<typename detail::decltype_t<T>::type...>>; }
constexpr auto operator()(T const& ...) const
{ return hana::type<F<typename T::type...>>{}; }
};
//////////////////////////////////////////////////////////////////////////
@@ -150,9 +150,8 @@ BOOST_HANA_NAMESPACE_BEGIN
using apply = F<T...>;
template <typename ...T>
constexpr auto operator()(T&& ...) const -> hana::type<
typename F<typename detail::decltype_t<T>::type...>::type
> { return {}; }
constexpr hana::type<typename F<typename T::type...>::type>
operator()(T const& ...) const { return {}; }
};
//////////////////////////////////////////////////////////////////////////
@@ -179,10 +178,8 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename F>
struct integral_t {
template <typename ...T>
constexpr auto operator()(T&& ...) const {
using Result = typename F::template apply<
typename detail::decltype_t<T>::type...
>::type;
constexpr auto operator()(T const& ...) const {
using Result = typename F::template apply<typename T::type...>::type;
return Result{};
}
};

View File

@@ -115,16 +115,6 @@ int main() {
to_list(foldable(type_c<t1>, type_c<t2>, type_c<t3>, type_c<t4>)),
mpl::list<t1, t2, t3, t4>{}
));
BOOST_HANA_CONSTANT_CHECK(equal(
to_list(foldable(1, '2', 3.0)),
mpl::list<int, char, double>{}
));
BOOST_HANA_CONSTANT_CHECK(equal(
to_list(foldable(1, type_c<t1>, 3.0)),
mpl::list<int, t1, double>{}
));
}
//////////////////////////////////////////////////////////////////////////

View File

@@ -115,16 +115,6 @@ int main() {
to_vec(foldable(type_c<t1>, type_c<t2>, type_c<t3>, type_c<t4>)),
mpl::vector<t1, t2, t3, t4>{}
));
BOOST_HANA_CONSTANT_CHECK(equal(
to_vec(foldable(1, '2', 3.0)),
mpl::vector<int, char, double>{}
));
BOOST_HANA_CONSTANT_CHECK(equal(
to_vec(foldable(1, type_c<t1>, 3.0)),
mpl::vector<int, t1, double>{}
));
}
//////////////////////////////////////////////////////////////////////////

View File

@@ -56,53 +56,6 @@ static_assert(!valid_call(hana::metafunction<no_type>, hana::type_c<x1>), "");
static_assert(hana::Metafunction<decltype(hana::metafunction<f>)>::value, "");
static_assert(hana::Metafunction<decltype(hana::metafunction<f>)&>::value, "");
// `metafunction` with non-type arguments
// 1 arg
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(y1{}),
hana::metafunction<f>(hana::type_c<y1>)
));
// 2 args
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(hana::type_c<x1>, y2{}),
hana::metafunction<f>(hana::type_c<x1>, hana::type_c<y2>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(y1{}, hana::type_c<x2>),
hana::metafunction<f>(hana::type_c<y1>, hana::type_c<x2>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(y1{}, y2{}),
hana::metafunction<f>(hana::type_c<y1>, hana::type_c<y2>)
));
// 3 args
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(hana::type_c<x1>, hana::type_c<x2>, y3{}),
hana::metafunction<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(hana::type_c<x1>, y2{}, hana::type_c<x3>),
hana::metafunction<f>(hana::type_c<x1>, hana::type_c<y2>, hana::type_c<x3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(hana::type_c<x1>, y2{}, y3{}),
hana::metafunction<f>(hana::type_c<x1>, hana::type_c<y2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(y1{}, hana::type_c<x2>, hana::type_c<x3>),
hana::metafunction<f>(hana::type_c<y1>, hana::type_c<x2>, hana::type_c<x3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(y1{}, hana::type_c<x2>, y3{}),
hana::metafunction<f>(hana::type_c<y1>, hana::type_c<x2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction<f>(y1{}, y2{}, y3{}),
hana::metafunction<f>(hana::type_c<y1>, hana::type_c<y2>, hana::type_c<y3>)
));
// Make sure we don't read from a non-constexpr variable
int main() {

View File

@@ -53,53 +53,6 @@ static_assert(!valid_call(hana::metafunction_class<no_type>, hana::type_c<x1>),
static_assert(hana::Metafunction<decltype(hana::metafunction_class<f>)>::value, "");
static_assert(hana::Metafunction<decltype(hana::metafunction_class<f>)&>::value, "");
// `metafunction_class` with non-type arguments
// 1 arg
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(y1{}),
hana::metafunction_class<f>(hana::type_c<y1>)
));
// 2 args
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(hana::type_c<x1>, y2{}),
hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<y2>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(y1{}, hana::type_c<x2>),
hana::metafunction_class<f>(hana::type_c<y1>, hana::type_c<x2>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(y1{}, y2{}),
hana::metafunction_class<f>(hana::type_c<y1>, hana::type_c<y2>)
));
// 3 args
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<x2>, y3{}),
hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(hana::type_c<x1>, y2{}, hana::type_c<x3>),
hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<y2>, hana::type_c<x3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(hana::type_c<x1>, y2{}, y3{}),
hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<y2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(y1{}, hana::type_c<x2>, hana::type_c<x3>),
hana::metafunction_class<f>(hana::type_c<y1>, hana::type_c<x2>, hana::type_c<x3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(y1{}, hana::type_c<x2>, y3{}),
hana::metafunction_class<f>(hana::type_c<y1>, hana::type_c<x2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::metafunction_class<f>(y1{}, y2{}, y3{}),
hana::metafunction_class<f>(hana::type_c<y1>, hana::type_c<y2>, hana::type_c<y3>)
));
// Make sure we don't read from a non-constexpr variable
int main() {

View File

@@ -42,53 +42,6 @@ static_assert(std::is_same<F::apply<x1, x2, x3>::type, f<x1, x2, x3>>{}, "");
static_assert(hana::Metafunction<decltype(hana::template_<f>)>::value, "");
static_assert(hana::Metafunction<decltype(hana::template_<f>)&>::value, "");
// `template_` with non-type arguments
// 1 arg
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(y1{}),
hana::template_<f>(hana::type_c<y1>)
));
// 2 args
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(hana::type_c<x1>, y2{}),
hana::template_<f>(hana::type_c<x1>, hana::type_c<y2>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(y1{}, hana::type_c<x2>),
hana::template_<f>(hana::type_c<y1>, hana::type_c<x2>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(y1{}, y2{}),
hana::template_<f>(hana::type_c<y1>, hana::type_c<y2>)
));
// 3 args
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(hana::type_c<x1>, hana::type_c<x2>, y3{}),
hana::template_<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(hana::type_c<x1>, y2{}, hana::type_c<x3>),
hana::template_<f>(hana::type_c<x1>, hana::type_c<y2>, hana::type_c<x3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(hana::type_c<x1>, y2{}, y3{}),
hana::template_<f>(hana::type_c<x1>, hana::type_c<y2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(y1{}, hana::type_c<x2>, hana::type_c<x3>),
hana::template_<f>(hana::type_c<y1>, hana::type_c<x2>, hana::type_c<x3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(y1{}, hana::type_c<x2>, y3{}),
hana::template_<f>(hana::type_c<y1>, hana::type_c<x2>, hana::type_c<y3>)
));
BOOST_HANA_CONSTANT_CHECK(hana::equal(
hana::template_<f>(y1{}, y2{}, y3{}),
hana::template_<f>(hana::type_c<y1>, hana::type_c<y2>, hana::type_c<y3>)
));
// Make sure we can use aliases
template <typename T> using alias = T;
static_assert(hana::template_<alias>(hana::type_c<x1>) == hana::type_c<x1>, "");