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...)