mirror of
https://github.com/boostorg/hana.git
synced 2026-02-15 13:12:12 +00:00
Add Typelist; an optimized List for types.
This commit is contained in:
@@ -45,5 +45,6 @@
|
||||
#include <boost/hana/range.hpp>
|
||||
#include <boost/hana/trait.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
#include <boost/hana/typelist.hpp>
|
||||
|
||||
#endif // !BOOST_HANA_HPP
|
||||
|
||||
92
include/boost/hana/typelist.hpp
Normal file
92
include/boost/hana/typelist.hpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/*!
|
||||
* @file
|
||||
* Defines `boost::hana::Typelist`.
|
||||
*
|
||||
*
|
||||
* @copyright Louis Dionne 2014
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE.md or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_TYPELIST_HPP
|
||||
#define BOOST_HANA_TYPELIST_HPP
|
||||
|
||||
#include <boost/hana/comparable.hpp>
|
||||
#include <boost/hana/detail/comparable_from_iterable.hpp>
|
||||
#include <boost/hana/detail/foldable_from_iterable.hpp>
|
||||
#include <boost/hana/detail/left_folds/variadic.hpp>
|
||||
#include <boost/hana/detail/left_folds/variadic_meta.hpp>
|
||||
#include <boost/hana/foldable.hpp>
|
||||
#include <boost/hana/functor.hpp>
|
||||
#include <boost/hana/integral.hpp>
|
||||
#include <boost/hana/iterable.hpp>
|
||||
#include <boost/hana/list.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup datatypes
|
||||
template <typename ...Xs>
|
||||
struct Typelist { };
|
||||
|
||||
template <typename ...Xs>
|
||||
constexpr auto typelist = Typelist<Xs...>{};
|
||||
|
||||
template <typename X, typename ...Xs>
|
||||
struct Iterable<Typelist<X, Xs...>> {
|
||||
static constexpr auto head_impl(Typelist<X, Xs...>)
|
||||
{ return type<X>; }
|
||||
|
||||
static constexpr auto tail_impl(Typelist<X, Xs...>)
|
||||
{ return typelist<Xs...>; }
|
||||
|
||||
static constexpr auto is_empty_impl(Typelist<X, Xs...>)
|
||||
{ return false_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Iterable<Typelist<>> {
|
||||
static constexpr auto is_empty_impl(Typelist<>)
|
||||
{ return true_; }
|
||||
};
|
||||
|
||||
template <typename ...Xs>
|
||||
struct Functor<Typelist<Xs...>> : defaults<Functor> {
|
||||
template <typename F>
|
||||
static constexpr auto fmap_impl(F f, Typelist<Xs...>)
|
||||
{ return list(f(type<Xs>)...); }
|
||||
|
||||
template <template <typename ...> class F>
|
||||
static constexpr auto fmap_impl(type_detail::Lift<F>, Typelist<Xs...>)
|
||||
{ return typelist<F<Xs>...>; }
|
||||
};
|
||||
|
||||
template <typename ...Xs>
|
||||
struct Foldable<Typelist<Xs...>> : detail::foldable_from_iterable {
|
||||
template <typename F, typename State>
|
||||
static constexpr auto foldl_impl(F f, State s, Typelist<Xs...>) {
|
||||
return detail::left_folds::variadic(f, s, type<Xs>...);
|
||||
}
|
||||
|
||||
template <template <typename ...> class F, typename State>
|
||||
static constexpr auto foldl_impl(type_detail::Lift<F>, Type<State>, Typelist<Xs...>) {
|
||||
return type<detail::left_folds::variadic_meta<F, State, Xs...>>;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ...Xs, typename ...Ys>
|
||||
struct Comparable<Typelist<Xs...>, Typelist<Ys...>>
|
||||
: detail::comparable_from_iterable
|
||||
{ };
|
||||
|
||||
template <typename ...Xs, typename ...Ys>
|
||||
constexpr auto operator==(Typelist<Xs...> xs, Typelist<Ys...> ys)
|
||||
{ return equal(xs, ys); }
|
||||
|
||||
template <typename ...Xs, typename ...Ys>
|
||||
constexpr auto operator!=(Typelist<Xs...> xs, Typelist<Ys...> ys)
|
||||
{ return not_equal(xs, ys); }
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_TYPELIST_HPP
|
||||
@@ -71,6 +71,10 @@ boost_hana_add_test(type.comparable)
|
||||
boost_hana_add_test(type.lift)
|
||||
boost_hana_add_test(type.traits)
|
||||
|
||||
boost_hana_add_test(typelist.comparable)
|
||||
boost_hana_add_test(typelist.functor)
|
||||
boost_hana_add_test(typelist.iterable)
|
||||
|
||||
|
||||
boost_hana_add_test(hana)
|
||||
boost_hana_add_test(misc.adl)
|
||||
|
||||
25
test/typelist/comparable.cpp
Normal file
25
test/typelist/comparable.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright Louis Dionne 2014
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE.md or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/hana/typelist.hpp>
|
||||
|
||||
#include <boost/hana/detail/static_assert.hpp>
|
||||
using namespace boost::hana;
|
||||
|
||||
|
||||
struct x0; struct x1; struct x2;
|
||||
|
||||
int main() {
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<> == typelist<>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<x0> != typelist<>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<> != typelist<x0>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<x0> == typelist<x0>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<x0, x1> != typelist<x0>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<x0> != typelist<x0, x1>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<x0, x1> == typelist<x0, x1>);
|
||||
BOOST_HANA_STATIC_ASSERT(typelist<x0, x1, x2> == typelist<x0, x1, x2>);
|
||||
}
|
||||
47
test/typelist/functor.cpp
Normal file
47
test/typelist/functor.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright Louis Dionne 2014
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE.md or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/hana/typelist.hpp>
|
||||
|
||||
#include <boost/hana/detail/static_assert.hpp>
|
||||
#include <boost/hana/list.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
using namespace boost::hana;
|
||||
|
||||
|
||||
struct x0; struct x1; struct x2;
|
||||
|
||||
|
||||
constexpr struct {
|
||||
constexpr auto operator()(Type<x0>) const { return 0; }
|
||||
constexpr auto operator()(Type<x1>) const { return 1; }
|
||||
constexpr auto operator()(Type<x2>) const { return 2; }
|
||||
} fv{};
|
||||
|
||||
void test_values() {
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(fv, typelist<>) == list());
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(fv, typelist<x0>) == list(0));
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(fv, typelist<x0, x1>) == list(0, 1));
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(fv, typelist<x0, x1, x2>) == list(0, 1, 2));
|
||||
}
|
||||
|
||||
|
||||
template <typename ...> struct _ft { };
|
||||
constexpr auto ft = lift<_ft>;
|
||||
|
||||
void test_types() {
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(ft, typelist<>) == typelist<>);
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(ft, typelist<x0>) == typelist<_ft<x0>>);
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(ft, typelist<x0, x1>) == typelist<_ft<x0>, _ft<x1>>);
|
||||
BOOST_HANA_STATIC_ASSERT(fmap(ft, typelist<x0, x1, x2>) == typelist<_ft<x0>, _ft<x1>, _ft<x2>>);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
test_values();
|
||||
test_types();
|
||||
}
|
||||
29
test/typelist/iterable.cpp
Normal file
29
test/typelist/iterable.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright Louis Dionne 2014
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE.md or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/hana/typelist.hpp>
|
||||
|
||||
#include <boost/hana/detail/static_assert.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
using namespace boost::hana;
|
||||
|
||||
|
||||
struct x0; struct x1; struct x2;
|
||||
|
||||
int main() {
|
||||
BOOST_HANA_STATIC_ASSERT(is_empty(typelist<>));
|
||||
BOOST_HANA_STATIC_ASSERT(!is_empty(typelist<x0>));
|
||||
BOOST_HANA_STATIC_ASSERT(!is_empty(typelist<x0, x1>));
|
||||
|
||||
BOOST_HANA_STATIC_ASSERT(head(typelist<x0>) == type<x0>);
|
||||
BOOST_HANA_STATIC_ASSERT(head(typelist<x0, x1>) == type<x0>);
|
||||
BOOST_HANA_STATIC_ASSERT(head(typelist<x0, x1, x2>) == type<x0>);
|
||||
|
||||
BOOST_HANA_STATIC_ASSERT(tail(typelist<x0>) == typelist<>);
|
||||
BOOST_HANA_STATIC_ASSERT(tail(typelist<x0, x1>) == typelist<x1>);
|
||||
BOOST_HANA_STATIC_ASSERT(tail(typelist<x0, x1, x2>) == typelist<x1, x2>);
|
||||
}
|
||||
Reference in New Issue
Block a user