diff --git a/doc/acknowledgements.htm b/doc/acknowledgements.htm deleted file mode 100644 index 38c8977..0000000 --- a/doc/acknowledgements.htm +++ /dev/null @@ -1,43 +0,0 @@ - -
- - -
- |
-
- Boost.Preprocessor-Acknowledgements- |
-
The original idea of passing two extra parameters to REPEAT, which makes it - possible to create preprocessor code on top of it, was due to Aleksey Gurtovoy. - The invokeable IDENTITY macro was also invented by him. He also suggested the - name for the library. Many thanks to Aleksey for his insights!
-Thanks to everyone who participated in the review: David Abrahams, Beman Dawes, - Ronald Garcia, Douglas Gregor, Aleksey Gurtovoy, Jeremy Siek, and Daryle Walker.
-Thanks to Chris Little and Mat Marcus for providing help with MWCW.
-The original automatic recursion technique, which makes many of the library -primitives easier to use, was invented by Paul Mensonides.
-The PREPROCESSOR library has been developed by Vesa Karvonen.
-Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/bibliography.htm b/doc/bibliography.htm deleted file mode 100644 index 44082e5..0000000 --- a/doc/bibliography.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Bibliography- |
-
Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/examples.htm b/doc/examples.htm deleted file mode 100644 index a4e93a7..0000000 --- a/doc/examples.htm +++ /dev/null @@ -1,91 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Examples- |
-
array_arithmetic.c | Implements over 2200 functions for 1-dimensional arithmetic -array manipulation in C. The idea is to use preprocessor data structures, -lists and tuples, for storing metainformation to be used for generating -the actual C code. |
catch_builtin.cpp | -Demonstrates the usage of lists and BOOST_PP_LIST_FOR_EACH(). | -
count_down.c | -Trivial example of using BOOST_PP_WHILE() that simply counts - down from N to 0 ultimately expanding to a 0. | -
delay.c | -Implements a macro whose expansion takes exponential amount - of time. | -
duffs_device.c | -Uses the preprocessor library to implement a generalized - macro for implementing a Duff's Device. | -
is_integral.cpp | -Demonstrates the usage of preprocessor lists for generating - C++ code. | -
linear_fib.c | -Shows how BOOST_PP_WHILE() can be used for implementing macros. | -
note.c | -Shows how BOOST_PP_STRINGIZE() can be used to allow macro - expansion before stringization. | -
repeat_2d.c | -Implements a generalized macro for 2D repetition using the - simple repetition primitives of the preprocessor library. | -
static_assert.c | -Shows how BOOST_PP_CAT() can be used to allow macro expansion - before token concatenation. | -
subscript_layer.cpp | -Shows how BOOST_PP_EMPTY can be used as an unused or empty - parameter. | -
Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/examples_preprocessed.htm b/doc/examples_preprocessed.htm deleted file mode 100644 index 6f0deb7..0000000 --- a/doc/examples_preprocessed.htm +++ /dev/null @@ -1,326 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Tutorial examples preprocessed- |
-
The following code snippets were produced by actually preprocessing the code - snippets of the tutorial. After preprocessing the code was reformatted manually.
- -EXAMPLE: - Use a Local Macro to avoid small scale repetition
- -template<class T, int n> -vec<T,n>& - operator += - ( vec<T,n>& - lhs - , const vec<T,n>& - rhs - ) -{ for (int i=0; i<n; ++i) - lhs(i) += rhs(i); - return lhs; -} - -template<class T, int n> -vec<T,n>& - operator -= - ( vec<T,n>& - lhs - , const vec<T,n>& - rhs - ) -{ for (int i=0; i<n; ++i) - lhs(i) -= rhs(i); - return lhs; -} - -template<class T, int n> -vec<T,n>& - operator *= - ( vec<T,n>& - lhs - , const vec<T,n>& - rhs - ) -{ for (int i=0; i<n; ++i) - lhs(i) *= rhs(i); - return lhs; -} - -template<class T, int n> -vec<T,n>& - operator /= - ( vec<T,n>& - lhs - , const vec<T,n>& - rhs - ) -{ for (int i=0; i<n; ++i) - lhs(i) /= rhs(i); - return lhs; -} -- -
EXAMPLE: - Use BOOST_PP_EMPTY() as an unused parameter in Local Macro instantiations
- -template<class base> -typename implement_subscript_using_begin_subscript<base>::value_type& - implement_subscript_using_begin_subscript<base>::operator[] - ( index_type - i - ) -{ return base::begin()[i]; -} - -template<class base> -const typename implement_subscript_using_begin_subscript<base>::value_type& - implement_subscript_using_begin_subscript<base>::operator[] - ( index_type - i - ) const -{ return base::begin()[i]; -} -- -
EXAMPLE: Use BOOST_PP_CAT instead of ## when necessary
- -enum -{ static_check_152 = (sizeof(int) <= sizeof(long)) ? 1 : -1 -}; -typedef char - static_assert_152 - [ static_check_152 - ]; --
EXAMPLE: Use BOOST_PP_STRINGIZE instead of # whenever necessary
-#pragma message("examples.cpp" "(" "20" ") : " "TBD!")-
EXAMPLE: - Use:
-to avoid O(N) repetition on lists in general
-struct make_type_list_end; - -template -< class T0=make_type_list_end -, class T1=make_type_list_end -, class T2=make_type_list_end -, class T3=make_type_list_end -, class T4=make_type_list_end -, class T5=make_type_list_end -, class T6=make_type_list_end -, class T7=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 - < T1 - , T2 - , T3 - , T4 - , T5 - , T6 - , T7 - > - >::type - > - >::type type; -}; -- -
EXAMPLE: - Use BOOST_PP_REPEAT and a Token Look-Up Function to eliminate categorical - repetition
- -catch (bool t) -{ report_typeid(t); - report_value(t); -} -catch (char t) -{ report_typeid(t); - report_value(t); -} -catch (signed char t) -{ report_typeid(t); - report_value(t); -} -catch (unsigned char t) -{ report_typeid(t); - report_value(t); -} -catch (short t) -{ report_typeid(t); - report_value(t); -} -catch (unsigned short t) -{ report_typeid(t); - report_value(t); -} -catch (int t) -{ report_typeid(t); - report_value(t); -} -catch (unsigned int t) -{ report_typeid(t); - report_value(t); -} -catch (long t) -{ report_typeid(t); - report_value(t); -} -catch (unsigned long t) -{ report_typeid(t); - report_value(t); -} -catch (float t) -{ report_typeid(t); - report_value(t); -} -catch (double t) -{ report_typeid(t); - report_value(t); -} -catch (long double t) -{ report_typeid(t); - report_value(t); -} -- -
EXAMPLE: - Use BOOST_PP_REPEAT_2ND to avoid O(N*N) repetition
- -vec() -{ -} -vec(T a0) -{ (*this)[0] = a0; -} -vec(T a0, T a1) -{ (*this)[0] = a0; - (*this)[1] = a1; -} -vec(T a0, T a1, T a2) -{ (*this)[0] = a0; - (*this)[1] = a1; - (*this)[2] = a2; -} -vec(T a0, T a1, T a2, T a3) -{ (*this)[0] = a0; - (*this)[1] = a1; - (*this)[2] = a2; - (*this)[3] = a3; -} -vec(T a0, T a1, T a2, T a3, T a4) -{ (*this)[0] = a0; - (*this)[1] = a1; - (*this)[2] = a2; - (*this)[3] = a3; - (*this)[4] = a4; -} -vec(T a0, T a1, T a2, T a3, T a4, T a5) -{ (*this)[0] = a0; - (*this)[1] = a1; - (*this)[2] = a2; - (*this)[3] = a3; - (*this)[4] = a4; - (*this)[5] = a5; -} -vec(T a0, T a1, T a2, T a3, T a4, T a5, T a6) -{ (*this)[0] = a0; - (*this)[1] = a1; - (*this)[2] = a2; - (*this)[3] = a3; - (*this)[4] = a4; - (*this)[5] = a5; - (*this)[6] = a6; -} -vec(T a0, T a1, T a2, T a3, T a4, T a5, T a6, T a7) -{ (*this)[0] = a0; - (*this)[1] = a1; - (*this)[2] = a2; - (*this)[3] = a3; - (*this)[4] = a4; - (*this)[5] = a5; - (*this)[6] = a6; - (*this)[7] = a7; -} -- -
-
EXAMPLE: - Use BOOST_PP_IF to implement special case for the first element
- -false == false; -true == true; -- -
-
EXAMPLE: Use arithmetic, logical and comparison operations when necessary
- -S, E0, E1 -E0, S, E1 -E0, E1, S -BAD PARAMS FOR SPECIAL_NUMBERED_LIST! E0, E1, E2, S- -
Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/index.htm b/doc/index.htm deleted file mode 100644 index 41eb4e2..0000000 --- a/doc/index.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Index- |
-
Revised - -
- -© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/keywords.txt b/doc/keywords.txt deleted file mode 100644 index 47568fd..0000000 --- a/doc/keywords.txt +++ /dev/null @@ -1,99 +0,0 @@ -BOOST_PP_ADD -BOOST_PP_ADD_D -BOOST_PP_AND -BOOST_PP_ASSERT_MSG -BOOST_PP_BOOL -BOOST_PP_CAT -BOOST_PP_COMMA -BOOST_PP_COMMA_IF -BOOST_PP_DEC -BOOST_PP_DIV -BOOST_PP_DIV_D -BOOST_PP_EMPTY -BOOST_PP_ENUM -BOOST_PP_ENUM_PARAMS -BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT -BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS -BOOST_PP_ENUM_SHIFTED -BOOST_PP_ENUM_SHIFTED_PARAMS -BOOST_PP_EQUAL -BOOST_PP_EQUAL_D -BOOST_PP_EXPAND -BOOST_PP_EXPR_IF -BOOST_PP_FOR -BOOST_PP_GREATER -BOOST_PP_GREATER_D -BOOST_PP_GREATER_EQUAL -BOOST_PP_GREATER_EQUAL_D -BOOST_PP_IDENTITY -BOOST_PP_IF -BOOST_PP_INC -BOOST_PP_LESS -BOOST_PP_LESS_D -BOOST_PP_LESS_EQUAL -BOOST_PP_LESS_EQUAL_D -BOOST_PP_LIMIT_DIM -BOOST_PP_LIMIT_MAG -BOOST_PP_LIMIT_TUPLE -BOOST_PP_LIST_APPEND -BOOST_PP_LIST_APPEND_D -BOOST_PP_LIST_AT -BOOST_PP_LIST_AT_D -BOOST_PP_LIST_CAT -BOOST_PP_LIST_CAT_D -BOOST_PP_LIST_CONS -BOOST_PP_LIST_ENUM -BOOST_PP_LIST_ENUM_R -BOOST_PP_LIST_FILTER -BOOST_PP_LIST_FILTER_D -BOOST_PP_LIST_FIRST -BOOST_PP_LIST_FIRST_N -BOOST_PP_LIST_FIRST_N_D -BOOST_PP_LIST_FOLD_LEFT -BOOST_PP_LIST_FOLD_LEFT_D -BOOST_PP_LIST_FOLD_RIGHT -BOOST_PP_LIST_FOLD_RIGHT_D -BOOST_PP_LIST_FOR_EACH -BOOST_PP_LIST_FOR_EACH_I -BOOST_PP_LIST_FOR_EACH_I_R -BOOST_PP_LIST_FOR_EACH_R -BOOST_PP_LIST_FOR_EACH_PRODUCT -BOOST_PP_LIST_FOR_EACH_PRODUCT_R -BOOST_PP_LIST_IS_CONS -BOOST_PP_LIST_IS_NIL -BOOST_PP_LIST_NIL -BOOST_PP_LIST_REST -BOOST_PP_LIST_REST_N -BOOST_PP_LIST_REST_N_D -BOOST_PP_LIST_REVERSE -BOOST_PP_LIST_REVERSE_D -BOOST_PP_LIST_SIZE -BOOST_PP_LIST_SIZE_D -BOOST_PP_LIST_TO_TUPLE -BOOST_PP_LIST_TO_TUPLE_R -BOOST_PP_LIST_TRANSFORM -BOOST_PP_LIST_TRANSFORM_D -BOOST_PP_MAX -BOOST_PP_MAX_D -BOOST_PP_MIN -BOOST_PP_MIN_D -BOOST_PP_MOD -BOOST_PP_MOD_D -BOOST_PP_MUL -BOOST_PP_MUL_D -BOOST_PP_NOR -BOOST_PP_NOT -BOOST_PP_NOT_EQUAL -BOOST_PP_NOT_EQUAL_D -BOOST_PP_OR -BOOST_PP_REPEAT -BOOST_PP_REPEAT_FROM_TO -BOOST_PP_STRINGIZE -BOOST_PP_SUB -BOOST_PP_SUB_D -BOOST_PP_TUPLE_EAT -BOOST_PP_TUPLE_ELEM -BOOST_PP_TUPLE_REVERSE -BOOST_PP_TUPLE_TO_LIST -BOOST_PP_WHILE -BOOST_PP_XOR diff --git a/doc/known_problems_with_cpp.htm b/doc/known_problems_with_cpp.htm deleted file mode 100644 index c1d13e7..0000000 --- a/doc/known_problems_with_cpp.htm +++ /dev/null @@ -1,125 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Widely known problems with the C preprocessor- |
-
Preprocessor metaprogramming is subject to heated discussions. Part of this is caused by -bad experiences with dangerous techniques, such as defining inline functions using macros. As a rule -of thumb, if you can find a clean and -manageable way to do something without using the preprocessor, then -you should do it that way.
- -Let's survey some of the widely known problems with the preprocessor in a problem/solution - format.
-PROBLEM: Preprocessor does not -respect scope, therefore macros can accidentally and sometimes silently replace -code.
- -SOLUTION A: Use all caps identifiers -for macros and only macros. This practically eliminates the possibility that a -macro might replace other kind of code accidentally.
- -SOLUTION B: Use the Local Macro -idiom:
- -#define MACRO ... -// Use MACRO -#undef MACRO -- -
This makes sure that a macro can not accidentally -replace code outside of the scope of the local macro.
-A problem with this solution is that the #undef can not be automated and may be -forgotten. Experienced programmers generally write the #undef either immediately -before (in time) or immediately after writing the macro definition.
-SOLUTION C: Use the Unique Macro Prefix idiom:
- -#define UMP_MACRO -// Use UMP_MACRO -- - -
This makes accidental substitution and collisions highly -unlikely. Problems with this solution:
-By combining all solutions, whenever -possible, the scope problem can be largely avoided.
-PROBLEM: Preprocessor code is difficult to read. -It requires understanding the basic process of how -the preprocessor recursively expands macros, finding the macro definition and mentally -substituting the parameters of the macro.
-SOLUTION: Any kind of programming requires basic understanding - of how the code is executed. Any parameterization technique, including simple - functions and templates requires finding the definition and mentally substituting - parameters.
-However, it is good to know a few techniques:
-An especially important thing to remember is to limit the use of preprocessor - to the structured, well understood and safe methods. Structure helps to understand - complex systems [McConnell].
-PROBLEM: "I'd -like to see Cpp abolished." - Bjarne Stroustrup in [Stroustrup]
-SOLUTION: The C preprocessor will be here for a -long time.
-In practice, preprocessor metaprogramming is far simpler and more portable - than template metaprogramming [Czarnecki].
-Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/problems_with_compilers.htm b/doc/problems_with_compilers.htm deleted file mode 100644 index 03bc664..0000000 --- a/doc/problems_with_compilers.htm +++ /dev/null @@ -1,138 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Known problems with specific compilers- |
-
Some compilers have buggy or limited preprocessors. This page explains known - problems with specific compilers.
-Metrowerks Codewarrior 7.0 has a bug in preprocessor (to be more - concrete, in function-like macro replacement mechanism) that restricts usage - of the library to only very simple cases, at least if you don't write code that - specifically address this issue; for example, the above NUMBERED_EXPRESSION - example doesn't compile on CW 7.0. Below is a simple test case that reproduces - the bug:
- -#define IDENTITY_MACRO(x) IDENTITY_MACRO_BODY(x) -#define IDENTITY_MACRO_BODY(x) x -#define COMMA_TOKEN() , -int a IDENTITY_MACRO(COMMA_TOKEN)() b; // this works -int c IDENTITY_MACRO(IDENTITY_MACRO(COMMA_TOKEN))() d; // this doesn't -- -
Basically, what's happening here is that function-like COMMA_TOKEN macro gets - expanded _inside_ of the nested IDENTITY_MACRO call - even although it's NOT - followed by a '(' as the next preprocessing token - which is a clearly an incorrect - behavior (see 16.3 [cpp.replace] para 9 for the detailed description of the - function-like macro replacement process). I've submitted a bug report, but they - haven't confirmed it yet.
-So, this is not a problem of the library, but probably something that needs - to be mentioned in the documentation, may be with some examples of how to workaround - the issue. Just to show one possible way around the problem, here is a NUMBERED_EXPRESSION - macro that does work on MWCW:
-#define NUMBERED_EXPRESSION(n, x) \ - BOOST_PP_CAT(BOOST_, \ - BOOST_PP_IF( \ - n \ - , PREPROCESSOR_IDENTITY(x##n) \ - , PREPROCESSOR_EMPTY \ - ))() \ -/**/ --
Reported by Aleksey Gurtovoy
- -It appears that their algorithm of macro call invocation is quite far - from ideal, because for the following code fragment (which is a part of - preprocessor_test.cpp), the - linear increasing of IS_FUNCTION_HELPER_TEST_MAX value leads to not even - quadratic, but something like exponential increasing of compilation time! - (see the timing data below). This behavior may or may not be problematic - for you, depending on how intense is your usage of the library. - -
#ifndef IS_FUNCTION_HELPER_TEST_MAX -#define IS_FUNCTION_HELPER_TEST_MAX 40 -#endif - -typedef char yes_type; - -#define IS_FUNCTION_HELPER(I,A)\ - template\ - <BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(I),class P)>\ - yes_type is_function_helper(\ - P0 (*)(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(I),P))); - -BOOST_PP_REPEAT_2ND(BOOST_PP_INC(IS_FUNCTION_HELPER_TEST_MAX),IS_FUNCTION_HELPER,A) - -#undef IS_FUNCTION_HELPER -- -
- | Comeau C/C++ 4.2.45.2 | -Microsoft Visual C++ 6.0 SP5 | -
---|---|---|
10 parameters | -< 1 sec | -< 1 sec | -
20 parameters | -~ 2 sec | -< 1 sec | -
30 parameters | -~ 15 sec | -< 1 sec | -
40 parameters | -~ 50 sec | -< 1 sec | -
Reported by Aleksey Gurtovoy
- -Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/doc/tutorial.htm b/doc/tutorial.htm deleted file mode 100644 index c803cbd..0000000 --- a/doc/tutorial.htm +++ /dev/null @@ -1,478 +0,0 @@ - - - - -
- |
-
- Boost.Preprocessor-Tutorial- |
-
The C++ function and template parameter lists are special syntactic constructs - and it is impossible to directly manipulate or generate them using C++ constructs. - This leads to unnecessary code repetition.
-Consider the implementation of the is_function<> metafunction in Boost. The - implementation uses an overloaded is_function_tester() function that is used - for testing if a type is convertible to pointer to a function. Because of the - special treatment of parameter lists, it is not possible to directly match a - function with an arbitrary parameter list. Instead, the is_function_tester() - must be overloaded for every distinct number of parameters that is to be supported. - Example:
- -template <class R> -yes_type is_function_tester(R (*)()); -template <class R, class A0> -yes_type is_function_tester(R (*)(A0)); -template <class R, class A0, A1> -yes_type is_function_tester(R (*)(A0, A1)); -template <class R, class A0, A1, A2> -yes_type is_function_tester(R (*)(A0, A1, A2)); - -// ... -- -
The need for this kind of repetition occurs particularly frequently while implementing - generic components or metaprogramming facilities, but the need also manifests - itself in many far simpler situations.
- -Typically the repetition is done manually. Manual code repetition is highly - unproductive, but sometimes more readable to the untrained eye.
-Another solution is to write an external program for generating the repeated - code or use some other extra linquistic means such as a smart editor. Unfortunately, - using external code generators has many disadvantages:
-Because C++ comes with a preprocessor, one would assume that it would support - these kind of needs directly. Using the preprocessor in this case is highly - desirable because:
-Most unfortunately, the preprocessor is a very low level preprocessor that - specifically does not support repetition or recursive macros. Library support - is needed!
-For detailed information on the capabilities and limitations of the preprocessor, - please refer to the C++ standard [Std].
-Using the primitives of the PREPROCESSOR library, the is_function_tester()s - could be implemented like this:
- -#define IS_FUNCTION_TESTER(N,_)\ - template<class R BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class A)>\ - yes_type is_function_tester(R (*)(BOOST_PP_ENUM_PARAMS(N,A))); - -BOOST_PP_REPEAT(BOOST_PP_INC(MAX_IS_FUNCTION_TESTER_PARAMS),IS_FUNCTION_TESTER,_) -#undef IS_FUNCTION_TESTER -- -
In order to change the maximum number of function parameters supported, you - now simply change the MAX_IS_FUNCTION_TESTER_PARAMS definition and recompile.
-The preprocessor metaprogramming techniques are presented in example format. -
-EXAMPLE: - Use a Local Macro to avoid small scale repetition
- -#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); \ - return lhs; \ - } - -BOOST_PP_DEF(+) -BOOST_PP_DEF(-) -BOOST_PP_DEF(*) -BOOST_PP_DEF(/) -#undef BOOST_PP_DEF -- -
TIP: It is usually okay to use a standard macro name like BOOST_PP_DEF - for this kind of code, because the macro is both defined and undefined in the - immediate site of its use.
-TIP: It is easier to verify proper use of -the line continuation operator when they are aligned.
-NOTES: You can extend this example by defining more and different kinds - of operators. Before doing so, consider using the Algebraic Categories technique - introduced in [Barton] or a Layered Architecture (see for instance - [Czarnecki]). However, at some point you must type the operator tokens - *, /, +, -, ..., because it is impossible to generate them using templates. - The resulting Categorical Repetition of tokens can be eliminated by using preprocessor - metaprogramming.
-EXAMPLE: - Use BOOST_PP_EMPTY as an unused parameter in Local Macro instantiations
- -#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(const BOOST_PP_EMPTY) -#undef BOOST_PP_DEF -- -
HOW: BOOST_PP_EMPTY() expands to nothing and can be used as - an unused parameter.
-NOTE: BOOST_PP_EMPTY without the () never gets expanded. The - () is necessary to invoke a function-like macro.
-CAVEAT: You can not safely use concatenation while using BOOST_PP_EMPTY(). -TIP: Occasionally one or two lines are -considerably longer than the rest. It can often save some work to not align all -of the line continuation operators without making the code too unreadable.
-TIP: Use syntax highlighting on preprocessor metaprogramming macro and - parameter identifiers such as
-It can greatly improve readability.
-EXAMPLE: Use BOOST_PP_CAT instead of ## when necessary
- -#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)); -- -
WHY: Macro expansion proceeds recursively in "layers". Token pasting - prevents the preprocessor from performing macro expansion, therefore it - is often necessary to delay token concatenation.
-EXAMPLE: Use BOOST_PP_STRINGIZE instead of # whenever necessary
- -#define NOTE(STR)\ - message(__FILE__ "(" BOOST_PP_STRINGIZE(__LINE__) ") : " STR) - -// ... - -#pragma NOTE("TBD!") -- -
WHY: Macro expansion proceeds recursively in "layers". Stringization - prevents the preprocessor from performing macro expansion, therefore it is often - necessary to delay stringization.
-EXAMPLE: - Use:
-to avoid O(N) repetition on lists in general
- -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; -}; -- -
HOW: BOOST_PP_REPEAT uses simulated recursion (pseudo code):
- -#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) -// ... -- -
BOOST_PP_ENUM_PARAMS variations use BOOST_PP_REPEAT
- -BOOST_PP_COMMA_IF(I) expands to a comma if I != 0.
- -BOOST_PP_INC(I) expands essentially to "I+1" and BOOST_PP_DEC(I) - expands essentially to "I-1".
- -EXAMPLE: Use a Conditional Define to -enable user configuration of code repetition based on need rather than some -"reasonable" upper limit
- -#ifndef MAKE_TYPE_LIST_MAX_LENGTH -#define MAKE_TYPE_LIST_MAX_LENGTH 8 -#endif -- -
Now the user can configure the make_type_list primitive without modifying library - code.
-EXAMPLE: - Use BOOST_PP_REPEAT and a Token Look-Up Function to eliminate categorical - repetition
- -// 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(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 - -// ... -- -
NOTE: The repetition of the above -example can be eliminated using template metaprogramming [Czarnecki] as well. However -categorical repetition of operator tokens can not be completely eliminated by -using template metaprogramming.
-EXAMPLE: - Use BOOST_PP_REPEAT to avoid O(N*N) repetition
- -#ifndef MAX_VEC_ARG_CNT -#define MAX_VEC_ARG_CNT 8 -#endif - -// ... - -#define ARG_FUN(I,_) BOOST_PP_COMMA_IF(I) T a##I -#define ASSIGN_FUN(I,_) (*this)[I] = a##I; - -#define DEF_VEC_CTOR_FUN(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 - -// ... -- -
HOW: BOOST_PP_REPEAT is implemented in a special way to enable -automatic recursion.
- -EXAMPLE: Use BOOST_PP_IF to implement special case for the first element
- -#define BOOST_PP_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; -- -
BOOST_PP_IF enables convenient generation of lists using BOOST_PP_REPEAT.
- -NOTE: THEN and ELSE don't have to be macros. However, if at least one - of them is a function-like macro and you want it to be expanded conditionally, - you have to make the other parameter a function-like macro, too. This can often - be done using BOOST_PP_IDENTITY. Consider the following example (by - Aleksey Gurtovoy):
- -#define NUMBERED_EXPRESSION(I,X)\ - BOOST_PP_IF \ - ( I \ - , BOOST_PP_IDENTITY(X##I) \ - , BOOST_PP_EMPTY \ - )()- -
NOTE: Like in the above implementation of COMMA_IF, the result of IF - is often invoked and not the THEN and ELSE parameters. If the parameters were - invoked, the code would not expand correctly, because the EMPTY parameter would - get expanded to nothing before the IF would be properly expanded.
-HOW: BOOST_PP_IF is defined for the entire repeat range (pseudo - code):
- -#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_IF2(THEN,ELSE) THEN -// ... -- -
EXAMPLE: Use arithmetic, logical and comparison operations when necessary
- -The PREPROCESSOR library supports saturated arithmetic, logical and -comparison operations on decimal integer literals in the range [0,BOOST_PP_LIMIT_MAG].
- -Suppose that you want to generate a numbered lists with a special element inserted - at a desired position. For example: E0, E1, S, E2. Consider the following example:
- -#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(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) -- -
Revised - - -
-© Copyright Housemarque Oy 2002
- -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with no claim as to its suitability -for any purpose.
- - diff --git a/test/arithmetic_test.cpp b/test/arithmetic_test.cpp deleted file mode 100644 index 3e9f520..0000000 --- a/test/arithmetic_test.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2001 - * Housemarque Oy - * http://www.housemarque.com - * - * Permission to copy, use, modify, sell and distribute this software is - * granted provided this copyright notice appears in all copies. This - * software is provided "as is" without express or implied warranty, and - * with no claim as to its suitability for any purpose. - * - * See http://www.boost.org for most recent version. - */ - -#include