2
0
mirror of https://github.com/boostorg/hana.git synced 2026-02-15 01:02:10 +00:00

Type: decouple library from its internal representation

This commit is contained in:
Louis Dionne
2014-06-09 10:39:05 -04:00
parent 2567066828
commit ee6c805ca8
6 changed files with 75 additions and 67 deletions

View File

@@ -2,6 +2,8 @@
@file
Defines `boost::hana::detail::left_folds::variadic`.
@todo Re-enable the optimization for `Type`s.
@copyright Louis Dionne 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
@@ -21,14 +23,15 @@ namespace boost { namespace hana { namespace detail { namespace left_folds {
constexpr auto operator()(F f, State s, Xs ...xs) const
{ return variadic_unrolled(f, s, xs...); }
template <template <typename ...> class F, typename State, typename ...Xs>
constexpr auto operator()(
type_detail::Template<F> f,
operators::_type<State> s,
operators::_type<Xs> ...xs) const
{
return type<variadic_meta<F, State, Xs...>>;
}
// template <template <typename ...> class F, typename State, typename ...Xs>
// constexpr auto operator()(
// type_detail::Template<F> f,
// operators::_type<State> s,
// operators::_type<Xs> ...xs) const
// {
// return type<variadic_meta<F, State, Xs...>>;
// }
} variadic{};
}}}} // end namespace boost::hana::detail::left_folds

View File

@@ -35,6 +35,7 @@ namespace boost { namespace hana {
@instantiates{Iterable, Functor, Foldable, Monad, Comparable}
@todo
- Re-enable the foldl optimization for type lists.
- It might be possible to optimize the implementation of homogeneous lists
using an array.
- Is it desirable to have different ways of creating lists, or should we
@@ -204,11 +205,11 @@ namespace boost { namespace hana {
return detail::left_folds::variadic(f, s, type<Xs>...);
}
template <template <typename ...> class F, typename State, typename ...Xs>
static constexpr auto
foldl_impl(type_detail::Template<F>, operators::_type<State>, operators::TypeList<Xs...>) {
return type<detail::left_folds::variadic_meta<F, State, Xs...>>;
}
// template <template <typename ...> class F, typename State, typename ...Xs>
// static constexpr auto
// foldl_impl(type_detail::Template<F>, operators::_type<State>, operators::TypeList<Xs...>) {
// return type<detail::left_folds::variadic_meta<F, State, Xs...>>;
// }
template <typename F, typename Xs>
static constexpr auto unpack_impl(F f, Xs xs)

View File

@@ -20,8 +20,12 @@ namespace boost { namespace hana { namespace trait {
template <template <typename ...> class Trait>
struct integral_trait {
template <typename ...T>
constexpr auto operator()(operators::_type<T>...) const
{ return integral<decltype(Trait<T...>::value), Trait<T...>::value>; }
constexpr auto operator()(T...) const {
return integral<
decltype(Trait<untype_t<T>...>::value),
Trait<untype_t<T>...>::value
>;
}
};
///////////////////
@@ -106,14 +110,15 @@ namespace boost { namespace hana { namespace trait {
constexpr auto rank = integral_trait<std::rank>{};
constexpr struct _extent {
template <typename T, typename N>
constexpr auto operator()(operators::_type<T>, N n) const {
constexpr auto operator()(T, N n) const {
return integral<
decltype(std::extent<T, n>::value), std::extent<T, n>::value
decltype(std::extent<untype_t<T>, n>::value),
std::extent<untype_t<T>, n>::value
>;
}
template <typename T>
constexpr auto operator()(operators::_type<T> t) const
constexpr auto operator()(T t) const
{ return (*this)(t, uint<0>); }
} extent{};
@@ -164,8 +169,8 @@ namespace boost { namespace hana { namespace trait {
constexpr struct _aligned_union {
template <typename Len, typename ...T>
constexpr auto operator()(Len len, operators::_type<T>...) const
{ return type<std::aligned_union_t<len, T...>>; }
constexpr auto operator()(Len len, T...) const
{ return type<std::aligned_union_t<len, untype_t<T>...>>; }
} aligned_union{};
constexpr auto decay = template_<std::decay_t>;

View File

@@ -23,7 +23,8 @@ namespace boost { namespace hana {
//! Wrapper to manipulate C++ types as constexpr objects.
//!
//! @todo
//! - Document the category theoretical foundation of the `Monad` instance.
//! - Completely figure out and document the category theoretical
//! foundation of this data type.
//! - Verify `Monad` laws.
//! - Move self-notes for `Type`-related stuff to the (internal?)
//! documentation of `Type`.
@@ -33,25 +34,45 @@ namespace boost { namespace hana {
//! - Add examples.
struct Type { };
namespace operators {
template <typename T>
struct _type {
using hana_datatype = Type;
using type = T;
};
}
//! Creates a `Type` representing `T`.
//! @relates Type
template <typename T>
constexpr operators::_type<T> type{};
BOOST_HANA_CONSTEXPR_LAMBDA auto type = [] {
struct wrapper : operators::enable {
using hana_datatype = Type;
using hidden = T;
};
return wrapper{};
}();
//! Metafunction returning the type represented by a `Type`.
//! @relates Type
//!
//! @note This operation is the inverse of `type`.
//!
//! @todo Explain why this must be a metafunction, with examples.
template <typename T>
struct untype {
using type = typename T::hidden;
};
//! Alias to `untype<T>::type`; provided for convenience.
//! @relates Type
template <typename T>
using untype_t = typename untype<T>::type;
//! Returns the type of an object as a `Type`.
//! @relates Type
BOOST_HANA_CONSTEXPR_LAMBDA auto decltype_ = [](auto t) {
return type<decltype(t)>;
};
namespace type_detail {
template <template <typename ...> class f>
struct Template {
template <typename ...Args>
constexpr auto operator()(operators::_type<Args>...) const
{ return type<f<Args...>>; }
constexpr auto operator()(Args...) const
{ return type<f<untype_t<Args>...>>; }
};
}
@@ -67,35 +88,14 @@ namespace boost { namespace hana {
template <template <typename ...> class f>
constexpr type_detail::Template<f> template_{};
struct _untype {
template <typename T>
constexpr T operator()(operators::_type<T>) const
{ return {}; }
};
//! Default constructs an object of the type wrapped in a `Type`.
//! @relates Type
//!
//! Obviously, this function can only be used when the wrapped type
//! is default constructible.
//!
//! @note This function is the inverse of `decltype_`.
constexpr _untype untype{};
//! Returns the type of an object as a `Type`.
//! @relates Type
BOOST_HANA_CONSTEXPR_LAMBDA auto decltype_ = [](auto t) {
return type<decltype(t)>;
};
template <>
struct Comparable<Type, Type> : defaults<Comparable> {
template <typename T, typename U>
static constexpr auto equal_impl(operators::_type<T>, operators::_type<U>)
static constexpr auto equal_impl(T, U)
{ return false_; }
template <typename T>
static constexpr auto equal_impl(operators::_type<T>, operators::_type<T>)
static constexpr auto equal_impl(T, T)
{ return true_; }
};
@@ -103,20 +103,19 @@ namespace boost { namespace hana {
template <>
struct Functor<Type> : defaults<Functor> {
template <typename F, typename T>
static constexpr auto fmap_impl(F f, operators::_type<T> t)
static constexpr auto fmap_impl(F f, T t)
{ return f(t); }
};
template <>
struct Monad<Type> : defaults<Monad> {
template <typename T>
static constexpr operators::_type<T> unit_impl(T)
{ return {}; }
static constexpr auto unit_impl(T t)
{ return decltype_(t); }
template <typename T>
static constexpr operators::_type<T>
join_impl(operators::_type<operators::_type<T>>)
{ return {}; }
static constexpr auto join_impl(T)
{ return untype_t<T>{}; }
};
}} // end namespace boost::hana

View File

@@ -18,10 +18,9 @@ struct x0; struct x1; struct x2;
namespace test_values {
constexpr struct {
//! @todo Decouple this from `Type`.
constexpr auto operator()(operators::_type<x0>) const { return 0; }
constexpr auto operator()(operators::_type<x1>) const { return 1; }
constexpr auto operator()(operators::_type<x2>) const { return 2; }
constexpr auto operator()(decltype(type<x0>)) const { return 0; }
constexpr auto operator()(decltype(type<x1>)) const { return 1; }
constexpr auto operator()(decltype(type<x2>)) const { return 2; }
} f{};
BOOST_HANA_CONSTEXPR_LAMBDA auto g = _ + int_<1>;

View File

@@ -6,6 +6,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/trait.hpp>
#include <boost/hana/detail/constexpr.hpp>
#include <boost/hana/detail/static_assert.hpp>
#include <boost/hana/integral.hpp>
#include <boost/hana/type.hpp>
@@ -14,8 +15,8 @@ using namespace boost::hana;
enum Enumeration { };
struct Structure { };
constexpr auto e = type<Enumeration>;
constexpr auto s = type<Structure>;
BOOST_HANA_CONSTEXPR_LAMBDA auto e = type<Enumeration>;
BOOST_HANA_CONSTEXPR_LAMBDA auto s = type<Structure>;
int main() {
// We just make sure that they compile. If the forwarding to `std::` is