Faster Recursive Template Compilation
30 March 2013bstamour brought an interesting point to my attention. The take away from it was a faster implementation of applyTuple from here that compiled quicker than my own implementation while still maintaining the same run-time equivalence.
This brings up an interesting angle to meta-programming in C++. While run-time performance is usually the highest priority, compile-time performance is an important metric to use too when designing a meta-programming algorithm.
Working with tuples part II
27 March 2013Synopsis
tuples2.cc:
void f(char& a, int& b, double& c, const char* d){
std::cout << "F called! " << a << " " << b << " " << c << " " << d << std::endl;
}
int main() {
auto tuple = make_tuple('a', 12, 3.14, "Test");
// from "mxcomp/tuple/printing.h"
printTuple(tuple);
// from "mxcomp/tuple/list.h"
printTuple(tail(tuple));
printTuple(append(tuple, std::string("String")));
applyTuple(f, tuple);
applyTuple( [](char&,int&,double&,char const*&) {
std::cout << "Lambda called. " << std::endl;
}, tuple);
auto sTuple = make_tuple(A(), B(), C(), D());
printTuple<PrintType>( ofType<A>(sTuple) );
printTuple<PrintType>( ofType<C>(sTuple) );
return 0;
}
Working with tuples
16 March 2013Synopsis
Efficiently do things like:
struct PrintFunctor {
template <typename T>
size_t operator()( T& s) {
std::cout << s << std::endl;
return sizeof(T);
}
template <typename T>
size_t operator()(size_t i, T& s) {
std::cout << i << ": " << s << std::endl;
return sizeof(T) + i;
}
};
int main(){
auto tuple = std::make_tuple("Hello", 12, 'w');
PrintFunctor functor;
// Print 'Hello'
tupleExt::run(functor, 0, tuple);
// Print '12'
size_t size = tupleExt::get(functor, 1, tuple);
// Print 'is size 4' (Or whatever sizeof(int) is on your system).
std::cout << "Is size " << size << std::endl;
// Print 'Hello', '12', 'w' each on its own line.
tupleExt::iterate(functor, tuple);
// Print '0: Hello', '1: 12', '2: w' each on its own line.
tupleExt::iterate_i(functor, tuple);
// Print 'Hello', '12', 'w' each on its own line.
// but also returns a vector with all the sizes mapped.
std::vector<size_t> sizes = tupleExt::to_vector(functor, tuple);
// Print 13 -- the addition of all the types in the tuple
std::cout << tupleExt::fold(functor, tuple, 0) << std::endl;
}
A cleaner way to do tuple iteration
14 March 2013In my previous post I gave examples on how to iterate over a tuple via recursive instantiations. It became a bit of an annoyance to keep doing this, so I played around until I found something better. Assuming library code exists somewhere that looks a little like so:
namespace tupleExt {
template <typename F>
struct With {
template <std::size_t N = 0, typename... Args, typename... FArgs>
static inline typename std::enable_if<N == sizeof...(Args), void>::type
iterate(const std::tuple<Args...>& t, FArgs&...){ }
template <std::size_t N = 0, typename... Args, typename... FArgs>
static inline typename std::enable_if<N < sizeof...(Args), void>::type
iterate(const std::tuple<Args...>& t, FArgs&... fargs){
F::evaluate( std::get<N>(t), fargs... );
iterate<N+1, Args...>(t, fargs...);
}
};
}
(More...)
Reflection in C++11
14 March 2013In recent years, with the reflective power of languages like Python and C#, the best way to add reflection to C++ has developed into an interesting discussion.
As it currently exists, the only core language features that enable anything nearing reflection are dynamic_cast and typeid the operators. These operators, while useful in their own right, tell us extremely little about a given object. In particular, what people have come now to expect from reflection is a list of class members with associated types and names.
One of the most common uses of reflection is for data serialization. For example, C# MVC has a one line invocation to serialize a given class to JSON. Obviously this doesn't work in all cases since C# is more expressive than JSON properly allows (For instance, circular references are hard, if not impossible, to represent in a standard way). But it does work most of the time, and is in particular useful when you are constructing small, data only objects which you want to use as a data exchange with an AJAX web app.
(More...)