2
0
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:
Louis Dionne
2014-05-25 11:06:18 -04:00
parent 316f6a14ec
commit d2f725f6fe
6 changed files with 198 additions and 0 deletions

View File

@@ -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

View 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

View File

@@ -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)

View 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
View 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();
}

View 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>);
}