C/C++ Preprocessor Metaprogramming - Applications: Typedef Unrolling

Another use for metaprogramming is when you want to have multiple typedef for variable parameters. An example of this is say you have a Vector class and we want typdef it for various dimensions and various data types.

template<int NUM_DIMENSIONS, class DataType>
struct Vector {
  DataType m_data[NUM_DIMENSIONS;
};

typedef Vector<2, int> Vector2i;
typedef Vector<2, double> Vector2d;
typedef Vector<2, float> Vector2f;

typedef Vector<3, int> Vector3i;
typedef Vector<3, double> Vector3d;
typedef Vector<3, float> Vector3f;

Suppose we wanted to expand this for more dimensions and data types as well. We can make use of pattern matching and FOR_EACH_2D to make our life easier.

// Pattern match PREFIX so that we can get a prefix if appropriate
// Otherwise return the type itself
#define PREFIX_int EXISTS(i)
#define PREFIX_float EXISTS(f)
#define PREFIX_double EXISTS(d)
#define GET_PREFIX(type) TRY_EXTRACT_EXISTS(CAT(PREFIX_, type), type)

#define DEFINE_VECTOR_TYPE(n, type) \
  typedef Vector<n, type> CAT(CAT(Vector, n), GET_PREFIX(type));

FOR_EACH_2D(DEFINE_VECTOR_TYPE, (2, 3, 4), (int, double, float))
/* Expands to
  typedef Vector<2, int> Vector2i;
  typedef Vector<2, double> Vector2d;
  typedef Vector<2, float> Vector2f;

  typedef Vector<3, int> Vector3i;
  typedef Vector<3, double> Vector3d;
  typedef Vector<3, float> Vector3f;

  typedef Vector<4, int> Vector4i;
  typedef Vector<4, double> Vector4d;
  typedef Vector<4, float> Vector4f;
*/
#undef DEFINE_VECTOR_TYPE