In part I and part II we played around with different constructs inside C++ templates. Now we’re ready to tackling something a bit meatier - sorting a list at compile time!
Recall from the previous sections that when working with template meta-programming that we’re dealing with programs whose functions take the form of templates and values take the form of types.
As a result, remember that that our lists are of the form:
Now to sort this list, we’re going to use a merge sort. The variant of this that we’re going to implement works as follows:
Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element is considered sorted).
Repeatedly merge sublists to produce new sorted sublists until there is only 1 sublist remaining. This will be the sorted list.
To write the first part, splitting the list into smaller parts, we’ll need a PAIR data type so we can split a list in to two parts. It’s tempting to create a struct with values for this, but remember, we want to allow the data type to hold arbitrary values from meta-programming, so it needs contain types (i.e. typedefs).
Now’re we’re able to write the first part of the mergesort algorithm, the split routine.
Note how we’ve used private typedefs to hold temporary values that are used to generate the public result type.
To write the second part, we’ll need to be able to merge two sorted lists together to make a single sorted list. This will require a conditional, an IF.
Here, we now have a IF template that we can use to generate conditionals. We’ve defined the general template at the top, and then in two
template specialisations we’ve defined the ELSE and THEN cases. To use it, we call it like so:
We can now write our MERGE template.
And finally, putting it all together, we can write a SORT that recurisively splits a list into smaller and smaller parts, and then merges them back together into a single sorted list.
And there we go - we’ve defined a list and sorted it, all at compile time.
Code for the examples in this post (and more!) are in the git repository at tmp-play.