diff --git a/identity_type/doc/html/index.html b/identity_type/doc/html/index.html index b7a5b38..b2f2e30 100644 --- a/identity_type/doc/html/index.html +++ b/identity_type/doc/html/index.html @@ -2,8 +2,7 @@ Caminiti

Distributed under the Boost Software License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt) -

Table of Contents

Motivation
Solution
Templates
Abstract Types
Compilers - and Platforms
Annex: Usage
Annex: +

Table of Contents

Motivation
Solution
Templates
Abstract Types
Annex: Usage
Annex: Implementation
Reference

This library allows to wrap type expressions within round parenthesis so they can be passed to macros even when they contain commas. @@ -37,21 +36,23 @@ 2

Note that, differently from the compiler, the preprocessor only recognizes - round parameters (). Angular - <> or squared [] parenthesis are not used by the preprocessor - when parsing the macro parameters. + round parenthesis (). Angular + <> and squared [] parenthesis are not recognized by the preprocessor + when parsing macro parameters.

Solution

In some cases, it might be possible to workaround this issue by avoiding to - pass the type expression to the macro all together. For example, in some cases - a typedef can be used to specify - the type expression with the commas outside the macro (see also var.cpp): + pass the type expression to the macro all together. For example, in the case + above a typedef could have been + used to specify the type expression with the commas outside the macro (see + also var.cpp):

typedef std::map<int, char> map_type;
 VAR(map_type, 3); // OK.
 

- When this is not possible or desired (e.g., see the function template f in the section below), the library header - boost/utility/identity_type.hpp + When this is neither possible nor desired (e.g., see the function template + f in the section below), this + library header boost/utility/identity_type.hpp defines a macro BOOST_IDENTITY_TYPE which can be used to workaround the issue while keeping the type expression as one of the macro parameters (see also var.cpp). @@ -61,15 +62,21 @@ VAR(BOOST_IDENTITY_TYPE((std::map<int, char>)), 4); // OK.

- This macro expands to an expression that evaluates (at compile-time) to the - specified type. The specified type is never split into multiple macro parameters - because it is always wrapped by a set of extra round parenthesis (). In fact, a total of two sets of round parenthesis - must be used: The parenthesis to invoke the macro BOOST_IDENTITY_TYPE(...) plus the inner parenthesis to wrap the + The BOOST_IDENTITY_TYPE macro + expands to an expression that evaluates (at compile-time) to the specified + type. The specified type is never split into multiple macro parameters because + it is always wrapped by a set of extra round parenthesis (). + In fact, a total of two sets of round parenthesis must be used: The parenthesis + to invoke the macro BOOST_IDENTITY_TYPE(...) plus the inner parenthesis to wrap the type passed to the macro BOOST_IDENTITY_TYPE((...)).

This macro works on any C++03 - compiler (because it does not use variadic - macros). [1] + compiler (and it does not use variadic + macros). [1] The authors originally developed and tested this library using + GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled + -std=c++0x) on Cygwin + and Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. See the library regressions + test results for more information on supported compilers and platforms.

Templates

This macro must be prefixed by typename when used within templates. For example, let's program a macro that declares @@ -95,11 +102,12 @@

However, note that the template parameter char - must be manually specified when invoking the function f<char>(a). In fact, + must be manually specified when invoking the function as in f<char>(a). In fact, when the BOOST_IDENTITY_TYPE macro is used to wrap a function template parameter, the template parameter can no longer be automatically deduced by the compiler form the function call - as in f(a). [2] (This limitation does not apply to class templates because class + as f(a) would + have done. [2] (This limitation does not apply to class templates because class template parameters must always be explicitly specified.) In other words, without using the BOOST_IDENTITY_TYPE macro, C++ would normally be able to automatically deduce the function template @@ -119,8 +127,7 @@

Abstract Types

On some compilers (e.g., GCC), using this macro on abstract types (i.e., classes with one or more pure virtual functions) generates a compiler error. This can - be worked around by manipulating the type adding and removing a reference to - it. + be avoided by manipulating the type adding and removing a reference to it.

Let's program a macro that performs a static assertion on a Template Meta-Programming (TMP) meta-function (similarly to Boost.MPL BOOST_MPL_ASSERT). The BOOST_IDENTITY_TYPE macro can be used @@ -148,25 +155,13 @@ >::type );

-

Compilers - and Platforms

- The authors originally developed and tested the library on: -

  1. - GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features - enabled -std=c++0x) on - Cygwin. -
  2. - Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. -

- See the library regressions - test results for detailed information on supported compilers and platforms.

Annex: Usage

The BOOST_IDENTITY_TYPE macro can be used either when calling a user-defined macro (as shown by the examples - so far), or internally in the definition of a user-defined macro (as shown - below). When BOOST_IDENTITY_TYPE - is used in the user macro definition, the call of the user macro will only - have to specify the extra parenthesis (see also paren.cpp): + so far), or internally when implementing a user-defined macro (as shown below). + When BOOST_IDENTITY_TYPE is + used in the implementation of the user-defined macro, the caller of the user + macro will have to specify the extra parenthesis (see also paren.cpp):

#define TMP_ASSERT_PAREN(parenthesized_metafunction) \
     /* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \
@@ -182,7 +177,7 @@
 TMP_ASSERT(BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)));
 

- However, note that the user will always have to specify + However, note that the caller will always have to specify the extra parenthesis even when the macro parameters contain no comma:

TMP_ASSERT_PAREN((boost::is_const<int const>)); // Always extra `((...))`.
@@ -191,8 +186,8 @@
 

In some cases, using BOOST_IDENTITY_TYPE - within the user macro definition might provide the best syntax for the user. - For example, this is the case for BOOST_MPL_ASSERT + in the implementation of the user-defined macro might provide the best syntax + for the caller. For example, this is the case for BOOST_MPL_ASSERT because the majority of template meta-programming expressions contain unwrapped commas so it is less confusing for the user to always specify the extra parenthesis ((...)) instead of using BOOST_IDENTITY_TYPE: @@ -215,7 +210,9 @@ Instead requiring the user to specify BOOST_IDENTITY_TYPE only when needed allows for the more natural syntax BOOST_LOCAL_FUNCTION(int& x, int& y) in the common cases when the parameter types - contain no comma. + contain no comma (while still allowing to specify parameter types with commas + as special cases using BOOST_LOCAL_FUNCTION(BOOST_IDENTITY_TYPE((std::map<int, char>))& + x, int& y)).

Annex: Implementation

The implementation of this library macro is equivalent to the following: [3] @@ -239,8 +236,8 @@ BOOST_IDENTITY_TYPE(parenthesized_type)

Macro BOOST_IDENTITY_TYPE

BOOST_IDENTITY_TYPE — This macro allows to wrap the specified type expression within extra round parenthesis so the type can be passed as a single macro parameter even if it contains commas (not already wrapped within round parenthesis).

Synopsis

// In header: <boost/utility/identity_type.hpp>
 
-BOOST_IDENTITY_TYPE(parenthesized_type)

Description

Parameters:

parenthesized_typeThe type expression to be passed as macro parameter wrapped by a single set of round parenthesis (...). This type expression can contain an arbitrary number of commas.

-

This macro works on any C++03 compiler (it does not require variadic macros).

This macro must be prefixed by typename when used within templates. However, the compiler will not be able to automatically determine function template parameters when they are wrapped with this macro (these parameters need to be explicitly specified when calling the function template).

On some compilers (like GCC), using this macro on an abstract types requires to add and remove a reference to the type.



[1] +BOOST_IDENTITY_TYPE(parenthesized_type)

Description

Parameters:

parenthesized_typeThe type expression to be passed as macro parameter wrapped by a single set of round parenthesis (...). This type expression can contain an arbitrary number of commas.

+

This macro works on any C++03 compiler (it does not use variadic macros).

This macro must be prefixed by typename when used within templates. Note that the compiler will not be able to automatically determine function template parameters when they are wrapped with this macro (these parameters need to be explicitly specified when calling the function template).

On some compilers (like GCC), using this macro on abstract types requires to add and remove a reference to the specified type.



[1] Using variadic macros, it would be possible to require a single set of extra parenthesis BOOST_IDENTITY_TYPE(type) instead of two BOOST_IDENTITY_TYPE((type)) but variadic macros are not part of C++03 (even if nowadays they are supported by most modern compilers and they are @@ -250,6 +247,6 @@ wraps the specified type within a meta-function.

[3] There is absolutely no guarantee that the macro is actually implemented using - the code listed in this documentation. This code is for explanatory purposes - only. + the code listed in this documentation. The listed code is for explanatory + purposes only.

diff --git a/identity_type/doc/identity_type.qbk b/identity_type/doc/identity_type.qbk index de8cfa1..ede7510 100644 --- a/identity_type/doc/identity_type.qbk +++ b/identity_type/doc/identity_type.qbk @@ -47,30 +47,32 @@ The preprocessor interprets that unwrapped comma as a separation between macro p # `char>` # `2` -Note that, differently from the compiler, the preprocessor only recognizes round parameters `()`. -Angular `<>` or squared `[]` parenthesis are not used by the preprocessor when parsing the macro parameters. +Note that, differently from the compiler, the preprocessor only recognizes round parenthesis `()`. +Angular `<>` and squared `[]` parenthesis are not recognized by the preprocessor when parsing macro parameters. [endsect] [section Solution] In some cases, it might be possible to workaround this issue by avoiding to pass the type expression to the macro all together. -For example, in some cases a `typedef` can be used to specify the type expression with the commas outside the macro (see also [@../../test/var.cpp =var.cpp=]): +For example, in the case above a `typedef` could have been used to specify the type expression with the commas outside the macro (see also [@../../test/var.cpp =var.cpp=]): [var_typedef] -When this is not possible or desired (e.g., see the function template `f` in the section below), the library header [headerref boost/utility/identity_type.hpp] defines a macro [macroref BOOST_IDENTITY_TYPE] which can be used to workaround the issue while keeping the type expression as one of the macro parameters (see also [@../../test/var.cpp =var.cpp=]). +When this is neither possible nor desired (e.g., see the function template `f` in the section below), this library header [headerref boost/utility/identity_type.hpp] defines a macro [macroref BOOST_IDENTITY_TYPE] which can be used to workaround the issue while keeping the type expression as one of the macro parameters (see also [@../../test/var.cpp =var.cpp=]). [var_ok] -This macro expands to an expression that evaluates (at compile-time) to the specified type. +The [macroref BOOST_IDENTITY_TYPE] macro expands to an expression that evaluates (at compile-time) to the specified type. The specified type is never split into multiple macro parameters because it is always wrapped by a set of extra round parenthesis `()`. In fact, a total of two sets of round parenthesis must be used: The parenthesis to invoke the macro `BOOST_IDENTITY_TYPE(...)` plus the inner parenthesis to wrap the type passed to the macro `BOOST_IDENTITY_TYPE((...))`. -This macro works on any [@http://www.open-std.org/JTC1/SC22/WG21/docs/standards C++03] compiler (because it does not use [@http://en.wikipedia.org/wiki/Variadic_macro variadic macros]). +This macro works on any [@http://www.open-std.org/JTC1/SC22/WG21/docs/standards C++03] compiler (and it does not use [@http://en.wikipedia.org/wiki/Variadic_macro variadic macros]). [footnote Using variadic macros, it would be possible to require a single set of extra parenthesis `BOOST_IDENTITY_TYPE(`[^['type]]`)` instead of two `BOOST_IDENTITY_TYPE((`[^['type]]`))` but variadic macros are not part of C++03 (even if nowadays they are supported by most modern compilers and they are also part of C++11). ] +The authors originally developed and tested this library using GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin and Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. +See the library [@http://www.boost.org/development/tests/release/developer/utility-identity_type.html regressions test results] for more information on supported compilers and platforms. [endsect] @@ -82,8 +84,8 @@ For example, let's program a macro that declares a function parameter named `arg [template_f_decl] [template_f_call] -However, note that the template parameter `char` must be manually specified when invoking the function `f(a)`. -In fact, when the [macroref BOOST_IDENTITY_TYPE] macro is used to wrap a function template parameter, the template parameter can no longer be automatically deduced by the compiler form the function call as in `f(a)`. +However, note that the template parameter `char` must be manually specified when invoking the function as in `f(a)`. +In fact, when the [macroref BOOST_IDENTITY_TYPE] macro is used to wrap a function template parameter, the template parameter can no longer be automatically deduced by the compiler form the function call as `f(a)` would have done. [footnote This is because the implementation of [macroref BOOST_IDENTITY_TYPE] wraps the specified type within a meta-function. ] @@ -98,7 +100,7 @@ In other words, without using the [macroref BOOST_IDENTITY_TYPE] macro, C++ woul [section Abstract Types] On some compilers (e.g., GCC), using this macro on abstract types (i.e., classes with one or more pure virtual functions) generates a compiler error. -This can be worked around by manipulating the type adding and removing a reference to it. +This can be avoided by manipulating the type adding and removing a reference to it. Let's program a macro that performs a static assertion on a [@http://en.wikipedia.org/wiki/Template_metaprogramming Template Meta-Programming] (TMP) meta-function (similarly to Boost.MPL [@http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html `BOOST_MPL_ASSERT`]). The [macroref BOOST_IDENTITY_TYPE] macro can be used to pass a meta-function with multiple template parameters to the assert macro (so to handle the commas separating the template parameters). @@ -108,29 +110,18 @@ In this case, if the meta-function is an abstract type, it needs to be manipulat [endsect] -[section Compilers and Platforms] - -The authors originally developed and tested the library on: - -# GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin. -# Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. - -See the library [@http://www.boost.org/development/tests/release/developer/utility-identity_type.html regressions test results] for detailed information on supported compilers and platforms. - -[endsect] - [section Annex: Usage] -The [macroref BOOST_IDENTITY_TYPE] macro can be used either when calling a user-defined macro (as shown by the examples so far), or internally in the definition of a user-defined macro (as shown below). -When [macroref BOOST_IDENTITY_TYPE] is used in the user macro definition, the call of the user macro will only have to specify the extra parenthesis (see also [@../../test/paren.cpp =paren.cpp=]): +The [macroref BOOST_IDENTITY_TYPE] macro can be used either when calling a user-defined macro (as shown by the examples so far), or internally when implementing a user-defined macro (as shown below). +When [macroref BOOST_IDENTITY_TYPE] is used in the implementation of the user-defined macro, the caller of the user macro will have to specify the extra parenthesis (see also [@../../test/paren.cpp =paren.cpp=]): [paren] -However, note that the user will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma: +However, note that the caller will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma: [paren_always] -In some cases, using [macroref BOOST_IDENTITY_TYPE] within the user macro definition might provide the best syntax for the user. +In some cases, using [macroref BOOST_IDENTITY_TYPE] in the implementation of the user-defined macro might provide the best syntax for the caller. For example, this is the case for `BOOST_MPL_ASSERT` because the majority of template meta-programming expressions contain unwrapped commas so it is less confusing for the user to always specify the extra parenthesis `((...))` instead of using [macroref BOOST_IDENTITY_TYPE]: BOOST_MPL_ASSERT(( // Natural syntax. @@ -147,7 +138,7 @@ For example, this is the case for [@http://www.boost.org/libs/local_function `BO return x + y; } BOOST_LOCAL_FUNCTION_NAME(add) -Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] only when needed allows for the more natural syntax `BOOST_LOCAL_FUNCTION(int& x, int& y)` in the common cases when the parameter types contain no comma. +Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] only when needed allows for the more natural syntax `BOOST_LOCAL_FUNCTION(int& x, int& y)` in the common cases when the parameter types contain no comma (while still allowing to specify parameter types with commas as special cases using `BOOST_LOCAL_FUNCTION(BOOST_IDENTITY_TYPE((std::map))& x, int& y)`). [endsect] @@ -156,7 +147,7 @@ Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] only when n The implementation of this library macro is equivalent to the following: [footnote There is absolutely no guarantee that the macro is actually implemented using the code listed in this documentation. -This code is for explanatory purposes only. +The listed code is for explanatory purposes only. ] #include diff --git a/include/boost/utility/identity_type.hpp b/include/boost/utility/identity_type.hpp index c297c49..4a1f6c4 100644 --- a/include/boost/utility/identity_type.hpp +++ b/include/boost/utility/identity_type.hpp @@ -28,14 +28,15 @@ This type expression can contain an arbitrary number of commas. } @EndParams -This macro works on any C++03 compiler (it does not require variadic macros). +This macro works on any C++03 compiler (it does not use variadic macros). This macro must be prefixed by typename when used within templates. -However, the compiler will not be able to automatically determine function template parameters when they are wrapped with this macro (these parameters need to -be explicitly specified when calling the function template). +Note that the compiler will not be able to automatically determine function +template parameters when they are wrapped with this macro (these parameters +need to be explicitly specified when calling the function template). -On some compilers (like GCC), using this macro on an abstract types requires to -add and remove a reference to the type. +On some compilers (like GCC), using this macro on abstract types requires to +add and remove a reference to the specified type. */ #define BOOST_IDENTITY_TYPE(parenthesized_type) \ /* must NOT prefix this with `::` to work with parenthesized syntax */ \