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