type_traits

Source code

Implementations of some type traits from C++17 and Lib Fundamentals v2 TS, and C++14-style type aliases for C++11.

template<bool B>
using tl::bool_constant = std::integral_constant<bool, B>
template<std::size_t N>
using tl::index_constant = std::integral_constant<std::size_t, N>
template<class...>
using tl::void_t = void

Turns any number of types into void.

This is useful as a metaprogramming trick.

template<template<class...> class Trait, class ...Args>
using tl::is_detected = magic

Checks if Trait<Args…> is a valid specialization. Implements std::experimental::is_detected from Lib Fundamentals V2 TS. Useful for detecting the presence of a given type member. Example:

template<class T>
using make_cute_t = decltype(std::declval<T>().make_cute());

template<class T>
using can_make_cute = tl::is_detected<make_cute_t, T>;

struct cat{ void make_cute(); };
struct abstract_concept_of_fear{};

static_assert(can_make_cute<cat>::value);
static_assert(!can_make_cute<abstract_concept_of_fear>::value);
template<typename T>
using tl::safe_underlying_type_t = magic

Like std::underlying_type, but if T is not an enum then there’s just no type member rather than being UB. Essentially implements P0340.

C++14-style alias templates

template<class T>
using tl::remove_cv_t = typename std::remove_cv<T>::type
template<class T>
using tl::remove_const_t = typename std::remove_const<T>::type
template<class T>
using tl::remove_volatile_t = typename std::remove_volatile<T>::type
template<class T>
using tl::add_cv_t = typename std::add_cv<T>::type
template<class T>
using tl::add_const_t = typename std::add_const<T>::type
template<class T>
using tl::add_volatile_t = typename std::add_volatile<T>::type
template<class T>
using tl::remove_reference_t = typename std::remove_reference<T>::type
template<class T>
using tl::add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type
template<class T>
using tl::add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type
template<class T>
using tl::remove_pointer_t = typename std::remove_pointer<T>::type
template<class T>
using tl::add_pointer_t = typename std::add_pointer<T>::type
template<class T>
using tl::make_signed_t = typename std::make_signed<T>::type
template<class T>
using tl::make_unsigned_t = typename std::make_unsigned<T>::type
template<class T>
using tl::remove_extent_t = typename std::remove_extent<T>::type
template<class T>
using tl::remove_all_extents_t = typename std::remove_all_extents<T>::type
template<std::size_t N, std::size_t AN>
using tl::aligned_storage_t = typename std::aligned_storage<N, A>::type
template<std::size_t N, class ...Ts>
using tl::aligned_union_t = typename std::aligned_union<N, Ts...>::type
template<class T>
using tl::decay_t = typename std::decay<T>::type
template<bool E, class Tvoid>
using tl::enable_if_t = typename std::enable_if<E, T>::type
template<bool B, class T, class F>
using tl::conditional_t = typename std::conditional<B, T, F>::type
template<class ...Ts>
using tl::common_type_t = typename std::common_type<Ts...>::type
template<class T>
using tl::underlying_type_t = typename std::underlying_type<T>::type
template<class T>
using tl::result_of_t = typename std::result_of<T>::type