#define BOOST_PP_DEF(op) /* ..................................... */ \ template<class T, int n> \ vec<T, n> operator op ## =(vec<T, n> lhs, const vec<T, n>& rhs) { \ for (int i = 0; i < n; ++i) { \ lhs(i) op ## = rhs(i); \ } \ } \ /**/ BOOST_PP_DEF(+) BOOST_PP_DEF(-) BOOST_PP_DEF(*) BOOST_PP_DEF(/) #undef BOOST_PP_DEF
BOOST_PP_DEF
for this kind of code
because the macro is both defined and undefined in the immediate site of its use.
*
, /
, +
, -
, etc.,
because it is impossible to generate them using templates.
The resulting categorical repetition of tokens can be eliminated by using preprocessor metaprogramming.
#define BOOST_PP_DEF(cv) /* ... */ \ template<class base> \ cv() typename implement_subscript_using_begin_subscript<base>::value_type& \ implement_subscript_using_begin_subscript<base>::operator[](index_type i) cv() { \ return base::begin()[i]; \ } \ /**/ BOOST_PP_DEF(BOOST_PP_EMPTY) BOOST_PP_DEF(BOOST_PP_IDENTITY(const))
#define STATIC_ASSERT(expr) \ enum { BOOST_PP_CAT(static_check_, __LINE__) = (expr) ? 1 : -1 }; \ typedef char \ BOOST_PP_CAT(static_assert_, __LINE__)[BOOST_PP_CAT(static_check_, __LINE__)] \ /**/ // ... STATIC_ASSERT(sizeof(int) <= sizeof(long));
#define NOTE(str) \ message(__FILE__ "(" BOOST_PP_STRINGIZE(__LINE__) ") : " str) \ /**/ // ... #pragma NOTE("TBD!")
struct make_type_list_end; template< BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( MAKE_TYPE_LIST_MAX_LENGTH, class T, make_type_list_end ) > struct make_type_list { private: enum { end = is_same<T0, make_type_list_end>::value }; public: typedef typename type_if< end, type_cons_empty, type_cons< T0, typename type_inner_if< end, type_identity<end>, make_type_list< BOOST_PP_ENUM_SHIFTED_PARAMS( MAKE_TYPE_LIST_MAX_LENGTH, T ) > >::type > >::type type; };
#define BOOST_PP_REPEAT(n, m, p) BOOST_PP_REPEAT ## n(m, p) #define BOOST_PP_REPEAT0(m, p) #define BOOST_PP_REPEAT1(m, p) m(0, p) #define BOOST_PP_REPEAT2(m, p) m(0, p) m(1, p) #define BOOST_PP_REPEAT3(m, p) BOOST_PP_REPEAT2(m, p) m(2, p) #define BOOST_PP_REPEAT4(m, p) BOOST_PP_REPEAT3(m, p) m(3, p) // ...
#ifndef MAKE_TYPE_LIST_MAX_LENGTH #define MAKE_TYPE_LIST_MAX_LENGTH 8 #endif
make_type_list
primitive without modifying library code.
// CAVEAT: My compiler is not standard on arithmetic types. #define ARITHMETIC_TYPE(I) ARITHMETIC_TYPE ## I #define ARITHMETIC_TYPE0 bool #define ARITHMETIC_TYPE1 char #define ARITHMETIC_TYPE2 signed char #define ARITHMETIC_TYPE3 unsigned char #define ARITHMETIC_TYPE4 short #define ARITHMETIC_TYPE5 unsigned short #define ARITHMETIC_TYPE6 int #define ARITHMETIC_TYPE7 unsigned int #define ARITHMETIC_TYPE8 long #define ARITHMETIC_TYPE9 unsigned long #define ARITHMETIC_TYPE10 float #define ARITHMETIC_TYPE11 double #define ARITHMETIC_TYPE12 long double #define ARITHMETIC_TYPE_CNT 13 // ... #define BOOST_PP_DEF(z, I, _) /* ... */ \ catch (ARITHMETIC_TYPE(I) t) { \ report_typeid(t); \ report_value(t); \ } \ /**/ BOOST_PP_REPEAT(ARITHMETIC_TYPE_CNT, BOOST_PP_DEF, _) #undef BOOST_PP_DEF
#ifndef MAX_VEC_ARG_CNT #define MAX_VEC_ARG_CNT 8 #endif // ... #define ARG_FUN(z, i, _) BOOST_PP_COMMA_IF(i) T a ## i #define ASSIGN_FUN(z, i, ) (*this)[i] = a ## i; #define DEF_VEC_CTOR_FUN(z, i, _) /* ... */ \ vec(BOOST_PP_REPEAT(i, ARG_FUN, _)) { \ BOOST_PP_REPEAT(i, ASSIGN_FUN, _) \ } \ /**/ BOOST_PP_REPEAT(BOOST_PP_INC(MAX_VEC_ARG_CNT), DEF_VEC_CTOR_FUN, _) #undef ARG_FUN #undef ASSIGN_FUN #undef DEF_VEC_CTOR_FUN // ...
#define COMMA_IF(c) \ BOOST_PP_IF(c, BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ /**/ BOOST_PP_IF(0, true, false) == false; BOOST_PP_IF(1, true, false) == true;
#define NUMBERED_EXPRESSION(i, x) /* ... */ \ BOOST_PP_IF( \ i, \ BOOST_PP_IDENTITY(x ## i) \ BOOST_PP_EMPTY \ )() \ /**/
#define BOOST_PP_IF(c, THEN, ELSE) BOOST_PP_IF ## c(THEN, ELSE) #define BOOST_PP_IF0(THEN, ELSE) ELSE #define BOOST_PP_IF1(THEN, ELSE) THEN #define BOOST_PP_IF1(THEN, ELSE) THEN // ...
#define SPECIAL_NUMBERED_LIST(n, i, elem, special) \ BOOST_PP_ASSERT_MSG( \ BOOST_PP_LESS(i, n), \ bad params for SPECIAL_NUMBERED_LIST! \ ) \ BOOST_PP_ENUM_PARAMS(i, elem) \ BOOST_PP_COMMA_IF(i) special \ BOOST_PP_REPEAT( \ BOOST_PP_SUB(BOOST_PP_DEC(n), i), \ SPECIAL_NUMBERED_LIST_HELPER, \ (elem, i) \ ) \ /**/ #define SPECIAL_NUMBERED_LIST_HELPER(z, i, elem_base) \ , \ BOOST_PP_CAT( \ BOOST_PP_TUPLE_ELEM(2, 0, elem_base), \ BOOST_PP_ADD( \ i, \ BOOST_PP_TUPLE_ELEM(2, 1, elem_base) \ ) \ ) \ /**/ SPECIAL_NUMBERED_LIST(3, 0, E, S) SPECIAL_NUMBERED_LIST(3, 1, E, S) SPECIAL_NUMBERED_LIST(3, 2, E, S) SPECIAL_NUMBERED_LIST(3, 3, E, S)
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)