diff --git a/identity_type/doc/html/index.html b/identity_type/doc/html/index.html index cc6f4b5..b7a5b38 100644 --- a/identity_type/doc/html/index.html +++ b/identity_type/doc/html/index.html @@ -2,7 +2,8 @@ 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
Annex: Usage
Annex: +

Table of Contents

Motivation
Solution
Templates
Abstract Types
Compilers + and Platforms
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. @@ -126,7 +127,7 @@ to pass a meta-function with multiple template parameters to the assert macro (so to handle the commas separating the template parameters). In this case, if the meta-function is an abstract type, it needs to be manipulated adding - and removing a reference to it (see also tmp_assert.cpp): + and removing a reference to it (see also abstract.cpp):

#define TMP_ASSERT(metafunction) \
     BOOST_STATIC_ASSERT(metafunction::value)
@@ -147,20 +148,36 @@
     >::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 tmp_assert.cpp): + 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 */ \
     BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value)
 
+#define TMP_ASSERT(metafunction) \
+    BOOST_STATIC_ASSERT(metafunction::value)
+
 // Specify only extra parenthesis `((...))`.
 TMP_ASSERT_PAREN((boost::is_const<std::map<int, char> const>));
+
 // Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro.
 TMP_ASSERT(BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)));
 

@@ -169,6 +186,7 @@ the extra parenthesis even when the macro parameters contain no comma:

TMP_ASSERT_PAREN((boost::is_const<int const>)); // Always extra `((...))`.
+
 TMP_ASSERT(boost::is_const<int const>); // No extra `((...))` and no macro.
 

@@ -221,7 +239,7 @@ 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.

+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] 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 diff --git a/identity_type/doc/identity_type.qbk b/identity_type/doc/identity_type.qbk index 3ef0b12..de8cfa1 100644 --- a/identity_type/doc/identity_type.qbk +++ b/identity_type/doc/identity_type.qbk @@ -24,7 +24,8 @@ This library allows to wrap type expressions within round parenthesis so they ca [import ../test/var_error.cpp] [import ../test/var.cpp] [import ../test/template.cpp] -[import ../test/tmp_assert.cpp] +[import ../test/abstract.cpp] +[import ../test/paren.cpp] [section Motivation] @@ -101,22 +102,33 @@ This can be worked around by manipulating the type adding and removing a referen 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). -In this case, if the meta-function is an abstract type, it needs to be manipulated adding and removing a reference to it (see also [@../../test/tmp_assert.cpp =tmp_assert.cpp=]): +In this case, if the meta-function is an abstract type, it needs to be manipulated adding and removing a reference to it (see also [@../../test/abstract.cpp =abstract.cpp=]): -[tmp_assert_abstract] +[abstract] + +[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/tmp_assert.cpp =tmp_assert.cpp=]): +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=]): -[tmp_assert_alternative] +[paren] However, note that the user will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma: -[tmp_assert_alternative_always] +[paren_always] In some cases, using [macroref 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` 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]: diff --git a/identity_type/test/Jamfile.v2 b/identity_type/test/Jamfile.v2 index 482c0c0..5cb5036 100644 --- a/identity_type/test/Jamfile.v2 +++ b/identity_type/test/Jamfile.v2 @@ -10,5 +10,7 @@ import testing ; compile-fail var_error.cpp ; run var.cpp ; run template.cpp ; -run tmp_assert.cpp ; +run abstract.cpp ; +run noncopyable.cpp ; +run paren.cpp ; diff --git a/identity_type/test/abstract.cpp b/identity_type/test/abstract.cpp new file mode 100644 index 0000000..39b10c3 --- /dev/null +++ b/identity_type/test/abstract.cpp @@ -0,0 +1,35 @@ + +// Copyright (C) 2009-2012 Lorenzo 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) +// Home at http://www.boost.org/libs/utility/identity_type + +#include +#include +#include +#include + +//[abstract +#define TMP_ASSERT(metafunction) \ + BOOST_STATIC_ASSERT(metafunction::value) + +template +struct abstract { + static const bool value = b; + virtual void f(T const& x) = 0; // Pure virtual function. +}; + +TMP_ASSERT( + boost::remove_reference< // Add and remove + BOOST_IDENTITY_TYPE(( // reference for + boost::add_reference< // abstract type. + abstract + >::type + )) + >::type +); +//] + +int main() { return 0; } + diff --git a/identity_type/test/noncopyable.cpp b/identity_type/test/noncopyable.cpp new file mode 100644 index 0000000..2819e68 --- /dev/null +++ b/identity_type/test/noncopyable.cpp @@ -0,0 +1,25 @@ + +// Copyright (C) 2009-2012 Lorenzo 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) +// Home at http://www.boost.org/libs/utility/identity_type + +#include +#include +#include + +//[noncopyable +#define TMP_ASSERT(metafunction) \ + BOOST_STATIC_ASSERT(metafunction::value) + +template +struct noncopyable : boost::noncopyable { + static const T value = init; +}; + +TMP_ASSERT(BOOST_IDENTITY_TYPE((noncopyable))); +//] + +int main() { return 0; } + diff --git a/identity_type/test/tmp_assert.cpp b/identity_type/test/paren.cpp similarity index 65% rename from identity_type/test/tmp_assert.cpp rename to identity_type/test/paren.cpp index b8be643..51b355f 100644 --- a/identity_type/test/tmp_assert.cpp +++ b/identity_type/test/paren.cpp @@ -8,44 +8,26 @@ #include #include #include -#include -#include #include -//[tmp_assert_abstract -#define TMP_ASSERT(metafunction) \ - BOOST_STATIC_ASSERT(metafunction::value) - -template -struct abstract { - static const bool value = b; - virtual void f(T const& x) = 0; // Pure virtual function. -}; - -TMP_ASSERT( - boost::remove_reference< // Add and remove - BOOST_IDENTITY_TYPE(( // reference for - boost::add_reference< // abstract type. - abstract - >::type - )) - >::type -); -//] - -//[tmp_assert_alternative +//[paren #define TMP_ASSERT_PAREN(parenthesized_metafunction) \ /* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \ BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value) +#define TMP_ASSERT(metafunction) \ + BOOST_STATIC_ASSERT(metafunction::value) + // Specify only extra parenthesis `((...))`. TMP_ASSERT_PAREN((boost::is_const const>)); + // Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro. TMP_ASSERT(BOOST_IDENTITY_TYPE((boost::is_const const>))); //] -//[tmp_assert_alternative_always +//[paren_always TMP_ASSERT_PAREN((boost::is_const)); // Always extra `((...))`. + TMP_ASSERT(boost::is_const); // No extra `((...))` and no macro. //]