"M:/ug/CPP-Dresden/2020-05_FastMeta/slides/src/docinfo-bespoke.html" "M:/ug/CPP-Dresden/2020-05_FastMeta/slides/src/docinfo-header-bespoke.html" "M:/ug/CPP-Dresden/2020-05_FastMeta/slides/src/docinfo-footer-bespoke.html" Faster ►► C++: Meta-Programming

Faster ►► C++

Meta-Programming

C++UG Dresden 2020

Andreas Reischuck

Meta Programming

What is it?

Generic Types

using IntVec = std::vector<int>;
using IntAndFloat = std::tuple<int, float>;
using IntOrFloat = std::variant<int, float>;

Generic Algorithms

template<class It, class Value>
auto find(It b, It e, const Value&) -> It;

auto vec = IntVec{1, 2, 3};
auto it = find(vec.begin(), vec.end(), 2);

Motivations

Fast to compile

Measure!

Time-Trace

clang -ftime-trace

single file

AST-Print

clang -Xclang -ast-print -fsyntax-only

Metashell

http://metashell.org/

Metabench

http://metaben.ch

Tools

Dig Deeper

Compare two types

STL usage

static_assert(std::is_same<int, int>::value);
static_assert(!std::is_same_v<int, float>);
template<class, class>
struct is_same : false_type {};

template<class T>
struct is_same<T, T> : true_type {};
template<class A, class B> constexpr
  auto is_same_v = is_same<A, B>::value;

Issues

1. Idea

template<class, class> constexpr
  auto is_same = false;

template<class T> constexpr
  auto is_same<T, T> = true;

Jorg Brown (CppCon 2019)

“Reducing Template Compilation Overhead, Using C++11, 14, 17, and 20.”

https://www.youtube.com/watch?v=TyiiNVA1syk

Wrapper (Slide 44/61)

template<class T>
struct Wrapper {
  static constexpr
    bool IsSame(Wrapper<T>*) { return true; }
  static constexpr
    bool IsSame(void*) { return false; }
};
static_assert(
  Wrapper<int>::IsSame((Wrapper<int>*)(nullptr)));

Wrapper with Base (Slide 46/61)

struct WrapperBase {
  static constexpr bool IsSame(void*) { return false; }
};
template<class T>
struct Wrapper : WrapperBase {
  static constexpr
    bool IsSame(Wrapper<T>*) { return true; }
  using WrapperBase::IsSame;
};
template<class A, class B>
using is_same = std::integral_constant<bool,
    Wrapper<A>::IsSame((Wrapper<B>*)(nullptr))>;

More Ideas?

Just Pointer

template<class T> using PtrTo = T*;
template<class T> constexpr
  auto is_same(T*, T*) { return true; }
constexpr
  auto is_same(...) { return false; }
static_assert(is_same(PtrTo<int>{}, PtrTo<int>{}));

Pointer to Type Pointers

template<class T> struct Type;
template<class T> constexpr
  auto type = (Type<T>*)(nullptr);
constexpr bool same(const void* a, const void* b) {
  return a == b;
}
static_assert(same(&type<int>, &type<int>));

Which strategy is best?

Benchmarks

Efforts for Metabench

Qbs module cpp_bench

New

Results

Same Clang-9 Compile Time

Same Clang-9 Ram Usage

Same Clang-9 AST line count

Same VS2019 Compile Time

Conclusion

Conditional Type

using X = conditional_t<true, int, float>;
static_assert(std::is_same_v<X, int>);
using Y = conditional_t<false, int, float>;
static_assert(std::is_same_v<Y, float>);
template<bool Cond, class Then, class Else>
using conditional_t =
    typename Conditional<Cond, Then, Else>::type;
template<bool Cond, class Then, class Else>
struct Conditional {
    using type = Then;
};
template<class Then, class Else>
struct Conditional<false, Then, Else> {
    using type = Else;
};
template<bool Cond> struct Conditional;

template<> struct Conditional<true> {
    template<class Then, class>
    using type = Then;
};
template<> struct Conditional<false> {
    template<class, class Else>
    using type = Else;
};

Conditional Benchmark Results

Conditional Clang-9 Compile Time

Conditional VS2019 Compile Time

Conclusion

Containers

Vector Contenders

Vector Benchmark Results

Vector Clang-9 Compile Time

Vector VS2019 Compile Time

Map Contenders

Map Clang-9 Compile Time

Map VS2019 Compile Time

Conclusion

Tuple

Tuple Contenders

Tuple Clang-9 Compile Time

Tuple VS2019 Compile Time

Tuple Visit Clang-9 Compile Time

Tuple Visit VS2019 Compile Time

Conclusion

Variant

Variant Contenders

Variant Clang-9 Compile Time

Variant VS2019 Compile Time

Variant Visit Clang-9 Compile Time

Variant Visit VS2019 Compile Time

Summary

andreas

 

hicknhackLogo new text

 

Work with us…

cppug

 

Give a Talk
⇒ get a Dresden tour

rebuild logo

Rebuild language project

 

Collaborate

Compile Benchmark your library!

co_await question_ready()