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:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user