c++ how i learned to stop worrying and love metaprogramming

19
1

Upload: cppfrug

Post on 17-Jul-2015

137 views

Category:

Technology


3 download

TRANSCRIPT

1

THE EXTREME DATABASE

WWW.QUASARDB.NET

2

MYTH: METAPROGRAMMING IS “USELESS”

3

Metaprogramming…

4

C++ 14…

5

Why metaprogramming?

6

Have the compiler generate the

correct program for you

• It knows things you don’t

• It will not be afraid to do tedious work

• It makes less mistakes than you

• Why write code when you could be

playing Baldur’s Gate 2 for the 10th

time?

Also: it’s awesome

A gentle introduction

7

int main(int argc, char ** argv)

{

static_assert(sizeof(int) == 4, "I want 32-bit integers!");

}

A more concrete example

8

#include <type_traits>

template <typename T>

T factorial(T v)

{

typedef typename std::integral_constant<T, 1> threshold;

static_assert(std::is_integral<T>::value, "I need an integral type");

return (v <= threshold::value) ? v : (v * factorial(v - 1));

}

A real metaprogram: compile time factorial

9

template <typename T, T v>

struct termination : std::conditional<v == 0, bool, void> {};

template <typename T, T v, typename Termination>

struct factorial_impl : std::integral_constant<T, v * factorial<T, v - 1>::type::value> {};

template <typename T, T v>

struct factorial_impl<T, v, bool> : std::integral_constant<T, 1> {};

template <typename T, T v, typename Termination = typename termination<T, v>::type>

struct factorial : factorial_impl<T, v, Termination> {};

10

C++ Metaprogramming :

Awesomeness overflow time

Also: typename.

The right code with tag dispatching

11

std::vector<int> v;

std::list<int> v;

template <typename Iterator>

void something_something_dark_side(Iterator first, Iterator last)

{

auto v = std::distance(first, last);

}

Wouldn’t it be cool to...

struct my_struct{

int alpha;std::string omega;

};

12

{"my_struct" : {

"alpha": 2,"omega": "boom"

}}

my_struct blah = { 2, ”boom” };auto boom = json::generate(json::from_fusion(blah));

Introducing Boost.Fusion

13

BOOST_FUSION_ADAPT_STRUCT(my_struct, (int, alpha)(std::string, omega))

• Compile time introspection

• Bridge between compile time and runtime

Example, set of various types:

boost::fusion::set<struct1, struct2> blah;

boost::fusion::at_key<struct1>(blah);

LET’S BE EXTREME

14

”Perfect” serialization

15

Goals

• Generate correct code

• Allocate memory only if needed

• Generate highly optimized code

• No ”if mess”

• Unintrusive

• More time for Baldur’s Gate 2

Implementing serialization

template <>struct codec<std::uint16_t, void>{

template <typename OutIt> static void encode(Outit & out,

boost::asio::mutable::buffer & sbuf, std::uint16_t i) {}

static boost::system::error_code decode(boost::asio::const_buffer & in,std::uint_16_t & i) {}

};

template <>struct scratch_size<std::uint16_t, void> :

boost::mpl::size_t<sizeof(std::uint16_t)> {};

16

Detect if alloc-free serialization is possible

17

struct static_size_tag { char pad; }; struct dynamic_size_tag { char pad[2]; };

template <typename T> struct is_static

{

template <typename U>

static static_size_tag dispatch(typename scratch_size<U>::type *) { return static_size_tag(); }

template <typename U> static dynamic_size_tag dispatch(...) { return dynamic_size_tag(); }

typedef is_static<T> type;

static const bool value = sizeof(dispatch<T>(nullptr)) == sizeof(static_size_tag);

};

The Metaprogrammer toolbox

18

• Clang 3.5+

• <type_traits>

• <tuples>

• Boost.MPL

• Boost.Fusion

• Boost.Hana - https://ldionne.github.io/hana/

MYTH: METAPROGRAMMING IS USELESS

19