CPP17 - yszheda/wiki Wiki

pmr

arena

structured binding

std::any

std::optional

std::string_view

ostream_joiner

std::void_t

// primary template handles types that do not support pre-increment:
template< class, class = void >
struct has_pre_increment_member : std::false_type { };
// specialization recognizes types that do support pre-increment:
template< class T >
struct has_pre_increment_member<T,
           std::void_t<decltype( ++std::declval<T&>() )>
       > : std::true_type { };
template<typename T, typename _ = void>
struct is_container : std::false_type {};

template<typename... Ts>
struct is_container_helper {};

template<typename T>
struct is_container<
        T,
        std::conditional_t<
            false,
            is_container_helper<
                typename T::value_type,
                typename T::size_type,
                typename T::allocator_type,
                typename T::iterator,
                typename T::const_iterator,
                decltype(std::declval<T>().size()),
                decltype(std::declval<T>().begin()),
                decltype(std::declval<T>().end()),
                decltype(std::declval<T>().cbegin()),
                decltype(std::declval<T>().cend())
                >,
            void
            >
        > : public std::true_type {};
#include <iostream>
#include <type_traits>
#include <vector>

template<typename ...>
using to_void = void; // maps everything to void, used in non-evaluated contexts

template<typename T, typename = void>
struct is_container : std::false_type
{};

template<typename T>
struct is_container<T,
        to_void<decltype(std::declval<T>().begin()),
                decltype(std::declval<T>().end()),
                typename T::value_type
        >> : std::true_type // will  be enabled for iterable objects
{};

template<typename T>
void f(T param, typename std::enable_if<is_container<T>::value>::type* = nullptr)
{
    std::cout << "Container\n";
}

template<typename T>
void f(T param, typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr)
{
    std::cout << "Fundamental\n";
}

template<typename T>
void f(T param, 
    typename std::enable_if<!std::is_fundamental<T>::value>::type* = nullptr, 
    typename std::enable_if<!is_container<T>::value>::type* = nullptr)
{
    std::cout << "Other\n";
}

struct Foo{};

int main()
{
    int x{};            // fundamental
    std::vector<int> v; // container
    Foo s{};    // other

    f(x);
    f(v);
    f(s);
}

std::make_from_tuple


namespace detail {
template <class T, class Tuple, std::size_t... I>
constexpr T make_from_tuple_impl( Tuple&& t, std::index_sequence<I...> )
{
    static_assert(std::is_constructible_v<T,
        decltype(std::get<I>(std::declval<Tuple>()))...>);
    return T(std::get<I>(std::forward<Tuple>(t))...);
}
} // namespace detail
 
template <class T, class Tuple>
constexpr T make_from_tuple( Tuple&& t )
{
    return detail::make_from_tuple_impl<T>(std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
}

constexpr

constexpr if

// before C++17
template<typename T>
std::enable_if_t<std::is_integral<T>::value, std::string> to_str(T t)
{
    return std::to_string(t);
}

template<typename T>
std::enable_if_t<!std::is_integral<T>::value, std::string> to_str(T t)
{
    return t;
}
// since C++17
template<typename T>
auto to_str17(T t)
{
    if constexpr(std::is_integral<T>::value)
        return std::to_string(t);
    else
        return t;
}

constexpr lambda

std::visit

std::is_invocable