Info
-
Did you know about memoized for less types (more compile-time friendly) conditional_t?
Example
namespace detail {
template <bool> struct conditional;
template <> struct conditional<false> {
template <class, class T> using fn = T;
};
template <> struct conditional<true> {
template <class T, class> using fn = T;
};
} // namespace detail
template <bool B, typename T, typename F>
using conditional_t = typename detail::conditional<B>::template fn<T, F>;
Puzzle
-
Can you implement tribool memoized version of conditional?
- Note: it should only instansiate 3 classes (for tribool) and use an alias for the T, F
template <auto B, class T, class F>
using conditional_t; // TODO - memoized for tribool
static_assert(conditional_t<true, std::true_type, std::false_type>{});
static_assert(not conditional_t<false, std::true_type, std::false_type>{});
static_assert(typeid(void) == typeid(conditional_t<boost::logic::indeterminate, std::true_type, std::false_type>{}));
Solutions
namespace detail {
template <auto>
struct conditional_t;
template <>
struct conditional_t<true> {
template <class T, class>
using meta_func = T;
};
template <>
struct conditional_t<false> {
template <class, class T>
using meta_func = T;
};
template <>
struct conditional_t<boost::logic::indeterminate> {
template <class, class>
using meta_func = void;
};
} // namespace detail
template <auto B, class T, class F>
using conditional_t = detail::conditional_t<B>::template meta_func<T, F>;
template <boost::logic::tribool>
struct conditional;
template <>
struct conditional<true> {
template <class T, class>
using fn = T;
};
template <>
struct conditional<false> {
template <class, class F>
using fn = F;
};
template <>
struct conditional<boost::logic::indeterminate> {
template <class, class>
using fn = void;
};
template <boost::logic::tribool B, class T, class F>
using conditional_t = boost::mp11::mp_invoke_q<conditional<B>, T, F>
template <auto B>
struct conditional;
template <>
struct conditional<true> {
template <class T, class>
…struct conditional<boost::logic::indeterminate> {
template <class, class>
using type = void;
};
template <auto B, class T, class F>
using conditional_t = typename conditional<B>::type<T, F>
namespace detail {
template <auto B>
struct conditional_impl;
template <>
using conditional_t = typename detail::conditional_impl<B>::type<T, F>
template <auto B> struct conditional{
template <class T, class F> using fn = void;
};
template <> struct conditional<false> {
template <class, class T> using fn = T;
};
template <> struct conditional<true> {
template <class T, class> using fn = T;
};
template <auto B, typename T, typename F>
using conditional_t = typename conditional<B>::template fn<T, F>;
namespace detail {
template <boost::logic::tribool> struct conditional;
template <> struct conditional<false> {
template <class, class T> using fn = T;
};
template <> struct conditional<true> {
template <class T, class> using fn = T;
};
template <> struct conditional<boost::logic::indeterminate> {
template <class, class> using fn = void;
};
}
namespace detail {
template <boost::tribool> struct conditional;
template <> struct conditional<false> {
template<class , class T> using fn = T;
};
template <> struct conditional<true> {
template<class T, class> using fn = T;
};
template<> struct conditional<boost::logic::indeterminate> {
template<class , class> using fn = void;
};
} //namespace detail
template <auto B, class T, class F>
using conditional_t = typename detail::conditional<B>::template fn<T, F>;