/*! @file Defines `boost::hana::type` and related utilities. Copyright Louis Dionne 2013-2022 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_HANA_TYPE_HPP #define BOOST_HANA_TYPE_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace hana { ////////////////////////////////////////////////////////////////////////// // basic_type ////////////////////////////////////////////////////////////////////////// //! @cond template struct basic_type : detail::operators::adl> { using hana_tag = type_tag; using type = T; constexpr auto operator+() const { return *this; } }; //! @endcond ////////////////////////////////////////////////////////////////////////// // type ////////////////////////////////////////////////////////////////////////// template struct type_impl { struct _ : basic_type { }; }; ////////////////////////////////////////////////////////////////////////// // decltype_ ////////////////////////////////////////////////////////////////////////// namespace detail { template struct decltype_t { using type = typename std::remove_reference::type; }; template struct decltype_t::type> { using type = typename std::remove_reference::type::type; }; } //! @cond template constexpr auto decltype_t::operator()(T&&) const { return hana::type_c::type>; } //! @endcond ////////////////////////////////////////////////////////////////////////// // typeid_ ////////////////////////////////////////////////////////////////////////// namespace detail { template struct typeid_t { using type = typename std::remove_cv< typename std::remove_reference::type >::type; }; template struct typeid_t::type> { using type = typename std::remove_reference::type::type; }; } //! @cond template constexpr auto typeid_t::operator()(T&&) const { return hana::type_c::type>; } //! @endcond ////////////////////////////////////////////////////////////////////////// // make ////////////////////////////////////////////////////////////////////////// template <> struct make_impl { template static constexpr auto apply(T&& t) { return hana::typeid_(static_cast(t)); } }; ////////////////////////////////////////////////////////////////////////// // sizeof_ ////////////////////////////////////////////////////////////////////////// //! @cond template constexpr auto sizeof_t::operator()(T&&) const { return hana::size_c::type)>; } //! @endcond ////////////////////////////////////////////////////////////////////////// // alignof_ ////////////////////////////////////////////////////////////////////////// //! @cond template constexpr auto alignof_t::operator()(T&&) const { return hana::size_c::type)>; } //! @endcond ////////////////////////////////////////////////////////////////////////// // is_valid ////////////////////////////////////////////////////////////////////////// namespace type_detail { template ()(std::declval()...) )> constexpr auto is_valid_impl(int) { return hana::true_c; } template constexpr auto is_valid_impl(...) { return hana::false_c; } template struct is_valid_fun { template constexpr auto operator()(Args&& ...) const { return is_valid_impl(int{}); } }; } //! @cond template constexpr auto is_valid_t::operator()(F&&) const { return type_detail::is_valid_fun{}; } template constexpr auto is_valid_t::operator()(F&&, Args&& ...) const { return type_detail::is_valid_impl(int{}); } //! @endcond ////////////////////////////////////////////////////////////////////////// // template_ ////////////////////////////////////////////////////////////////////////// // Note: We have to use the very complicated trick below instead of just // mentionning `F` in a SFINAE-able context because of CWG 1430 // (http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_active.html#1430). namespace template_detail { template struct args; template using always_void = void; template