diff --git a/static_assert.htm b/static_assert.htm index adfbb65..6e941de 100644 --- a/static_assert.htm +++ b/static_assert.htm @@ -1,58 +1,40 @@ - -
- - - -The header <boost/static_assert.hpp> supplies a single -macro BOOST_STATIC_ASSERT(x), which generates a compile time -error message if the integral-constant-expression -x is not true. In other words it is the compile time -equivalent of the assert macro; this is sometimes known as a -"compile-time-assertion", but will be called a "static -assertion" throughout these docs. Note that if the condition -is true, then the macro will generate neither code nor data - and -the macro can also be used at either namespace, class or function -scope. When used in a template, the static assertion will be -evaluated at the time the template is instantiated; this is -particularly useful for validating template parameters.
- -One of the aims of BOOST_STATIC_ASSERT is to generate readable -error messages. These immediately tell the user that a library is -being used in a manner that is not supported. While error -messages obviously differ from compiler to compiler, but you -should see something like:
- -Illegal use of COMPILE_TIME_ASSERTION_FAILURE<false>- -
Which is intended to at least catch the eye!
- -You can use BOOST_STATIC_ASSERT at any place where you can -place a declaration, that is at class, function or namespace -scope, this is illustrated by the following examples:
- -The macro can be used at namespace scope, if there is some -requirement must always be true; generally this means some -platform specific requirement. Suppose we require that int -be at least a 32-bit integral type, and that wchar_t be an -unsigned type. We can verify this at compile time as follows:
- -#include <climits> + +static assertions + + + + + ++
Header <boost/static_assert.hpp>
The header <boost/static_assert.hpp> supplies a single macro + BOOST_STATIC_ASSERT(x), which generates a compile time error message if the + integral-constant-expression x is not true. In other words it is + the compile time equivalent of the assert macro; this is sometimes known as a + "compile-time-assertion", but will be called a "static assertion" throughout + these docs. Note that if the condition is true, then the macro will generate + neither code nor data - and the macro can also be used at either namespace, + class or function scope. When used in a template, the static assertion will be + evaluated at the time the template is instantiated; this is particularly useful + for validating template parameters. +
+One of the aims of BOOST_STATIC_ASSERT is to generate readable error messages. + These immediately tell the user that a library is being used in a manner that + is not supported. While error messages obviously differ from compiler to + compiler, but you should see something like: +
+Illegal use of STATIC_ASSERTION_FAILURE<false>+Which is intended to at least catch the eye!
+You can use BOOST_STATIC_ASSERT at any place where you can place a declaration, + that is at class, function or + namespace scope, this is illustrated by the following examples:
+Use at namespace scope.
+The macro can be used at namespace scope, if there is some requirement must + always be true; generally this means some platform specific requirement. + Suppose we require that int be at least a 32-bit integral type, and that + wchar_t be an unsigned type. We can verify this at compile time as + follows:
+#include <climits> #include <cwchar> #include <boost/static_assert.hpp> @@ -63,40 +45,31 @@ BOOST_STATIC_ASSERT(WCHAR_MIN >= 0); } // namespace my_conditions- -The use of the namespace my_conditions here requires -some comment. The macro BOOST_STATIC_ASSERT works by generating -an typedef declaration, and since the typedef -must have a name, the macro generates one automatically by -mangling a stub name with the value of __LINE__. When -BOOST_STATIC_ASSERT is used at either class or function scope -then each use of BOOST_STATIC_ASSERT is guaranteed to produce a -name unique to that scope (provided you only use the macro once -on each line). However when used in a header at namespace scope, -that namespace can be continued over multiple headers, each of -which may have their own static assertions, and on the "same" -lines, thereby generating duplicate declarations. In theory the -compiler should silently ignore duplicate typedef declarations, -however many do not do so (and even if they do they are entitled -to emit warnings in such cases). To avoid potential problems, if -you use BOOST_STATIC_ASSERT in a header and at namespace scope, -then enclose them in a namespace unique to that header.
- -Use at function scope
- -The macro is typically used at function scope inside template -functions, when the template arguments need checking. Imagine -that we have an iterator-based algorithm that requires random -access iterators. If the algorithm is instantiated with iterators -that do not meet our requirements then an error will be generated -eventually, but this may be nested deep inside several templates, -making it hard for the user to determine what went wrong. One -option is to add a static assertion at the top level of the -template, in that case if the condition is not met, then an error -will be generated in a way that makes it reasonably obvious to -the user that the template is being misused.
- -#include <iterator> +The use of the namespace my_conditions here requires some comment. The + macro BOOST_STATIC_ASSERT works by generating an typedef declaration, + and since the typedef must have a name, the macro generates one automatically + by mangling a stub name with the value of __LINE__. When BOOST_STATIC_ASSERT is + used at either class or function scope then each use of BOOST_STATIC_ASSERT is + guaranteed to produce a name unique to that scope (provided you only use the + macro once on each line). However when used in a header at namespace scope, + that namespace can be continued over multiple headers, each of which may have + their own static assertions, and on the "same" lines, thereby generating + duplicate declarations. In theory the compiler should silently ignore duplicate + typedef declarations, however many do not do so (and even if they do they are + entitled to emit warnings in such cases). To avoid potential problems, if you + use BOOST_STATIC_ASSERT in a header and at namespace scope, then enclose them + in a namespace unique to that header.
+Use at function scope
+The macro is typically used at function scope inside template functions, when + the template arguments need checking. Imagine that we have an iterator-based + algorithm that requires random access iterators. If the algorithm is + instantiated with iterators that do not meet our requirements then an error + will be generated eventually, but this may be nested deep inside several + templates, making it hard for the user to determine what went wrong. One option + is to add a static assertion at the top level of the template, in that case if + the condition is not met, then an error will be generated in a way that makes + it reasonably obvious to the user that the template is being misused.
+#include <iterator> #include <boost/static_assert.hpp> #include <boost/type_traits.hpp> @@ -111,24 +84,19 @@ RandomAccessIterator foo(RandomAccessIterator from, RandomAccessIterator to) // detail goes here... return from; }- -A couple of footnotes are in order here: the extra set of -parenthesis around the assert, is to prevent the comma inside the -is_convertible template being interpreted by the preprocessor as -a macro argument separator; the target type for is_convertible is -a reference type, as some compilers have problems using -is_convertible when the conversion is via a user defined -constructor (in any case there is no guarantee that the iterator -tag classes are copy-constructible).
- -Use at class scope
- -The macro is typically used inside classes that are templates. -Suppose we have a template-class that requires an unsigned -integral type with at least 16-bits of precision as a template -argument, we can achieve this using something like this:
- -#include <climits> +A couple of footnotes are in order here: the extra set of parenthesis around + the assert, is to prevent the comma inside the is_convertible template being + interpreted by the preprocessor as a macro argument separator; the target type + for is_convertible is a reference type, as some compilers have problems using + is_convertible when the conversion is via a user defined constructor (in any + case there is no guarantee that the iterator tag classes are + copy-constructible).
+Use at class scope
+The macro is typically used inside classes that are templates. Suppose we have + a template-class that requires an unsigned integral type with at least 16-bits + of precision as a template argument, we can achieve this using something like + this:
+#include <climits> #include <boost/static_assert.hpp> template <class UnsignedInt> @@ -143,137 +111,112 @@ public: /* details here */ };- -How it works
- -BOOST_STATIC_ASSERT works as follows. There is class -STATIC_ASSERTION_FAILURE which is defined as:
- -namespace boost{ +How it works
+BOOST_STATIC_ASSERT works as follows. There is class STATIC_ASSERTION_FAILURE + which is defined as:
+namespace boost{ template <bool> struct STATIC_ASSERTION_FAILURE; template <> struct STATIC_ASSERTION_FAILURE<true>{}; }- -The key feature is that the error message triggered by the -undefined expression sizeof(STATIC_ASSERTION_FAILURE<0>), -tends to be consistent across a wide variety of compilers. The -rest of the machinery of BOOST_STATIC_ASSERT is just a way to -feed the sizeof expression into a typedef. The use of a macro -here is somewhat ugly; however boost members have spent -considerable effort trying to invent a static assert that avoided -macros, all to no avail. The general conclusion was that the good -of a static assert working at namespace, function, and class -scope outweighed the ugliness of a macro.
- -Test Programs
- -The following test programs are provided with this library:
- -
Test Program | -Expected to Compile | -Description | -
static_assert_test.cpp | -Yes | -Illustrates usage, and should always - compile, really just tests compiler compatibility. | -
static_assert_example_1.cpp | -Platform dependent. | -Namespace scope test program, may compile - depending upon the platform. | -
static_assert_example_2.cpp | -Yes | -Function scope test program. | -
static_assert_example_3.cpp | -Yes | -Class scope test program. | -
static_assert_test_fail_1.cpp | -No | -Illustrates failure at namespace scope. | -
static_assert_test_fail_2.cpp | -No | -Illustrates failure at non-template - function scope. | -
static_assert_test_fail_3.cpp | -No | -Illustrates failure at non-template class - scope. | -
static_assert_test_fail_4.cpp | -No | -Illustrates failure at non-template class - scope. | -
static_assert_test_fail_5.cpp | -No | -Illustrates failure at template class - scope. | -
static_assert_test_fail_6.cpp | -No | -Illustrates failure at template class - member function scope. | -
static_assert_test_fail_7.cpp | -No | -Illustrates failure of class scope - example. | -
static_assert_test_fail_8.cpp | -No | -Illustrates failure of function scope example. | -
static_assert_test_fail_9.cpp | -No | -Illustrates failure of function scope example (part 2). | -
Revised 27th Nov 2000
- -Documentation © Copyright John Maddock 2000. 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.
- -Based on contributions by Steve Cleary and John Maddock.
- -Maintained by John -Maddock, the latest version of this file can be found at www.boost.org, and the boost -discussion list at www.yahoogroups.com/list/boost. -
- -- -
- +
The key feature is that the error message triggered by the undefined expression + sizeof(STATIC_ASSERTION_FAILURE<0>), tends to be consistent across a wide + variety of compilers. The rest of the machinery of BOOST_STATIC_ASSERT is just + a way to feed the sizeof expression into a typedef. The use of a macro here is + somewhat ugly; however boost members have spent considerable effort trying to + invent a static assert that avoided macros, all to no avail. The general + conclusion was that the good of a static assert working at namespace, function, + and class scope outweighed the ugliness of a macro.
+The following test programs are provided with this library:
+Test Program | +Expected to Compile | +Description | +
static_assert_test.cpp | +Yes | +Illustrates usage, and should always compile, really just tests + compiler compatibility. | +
static_assert_example_1.cpp | +Platform dependent. | +Namespace scope test program, may compile depending upon the + platform. | +
static_assert_example_2.cpp | +Yes | +Function scope test program. | +
static_assert_example_3.cpp | +Yes | +Class scope test program. | +
static_assert_test_fail_1.cpp | +No | +Illustrates failure at namespace scope. | +
static_assert_test_fail_2.cpp | +No | +Illustrates failure at non-template function scope. | +
static_assert_test_fail_3.cpp | +No | +Illustrates failure at non-template class scope. | +
static_assert_test_fail_4.cpp | +No | +Illustrates failure at non-template class scope. | +
static_assert_test_fail_5.cpp | +No | +Illustrates failure at template class scope. | +
static_assert_test_fail_6.cpp | +No | +Illustrates failure at template class member function scope. | +
static_assert_test_fail_7.cpp | +No | +Illustrates failure of class scope example. | +
static_assert_test_fail_8.cpp | +No | +Illustrates failure of function scope example. | +
static_assert_test_fail_9.cpp | +No | +Illustrates failure of function scope example (part 2). | +
Revised 27th Nov 2000
+Documentation © Copyright John Maddock 2000. 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.
+Based on contributions by Steve Cleary and John Maddock.
+Maintained by John Maddock, the + latest version of this file can be found at www.boost.org, + and the boost discussion list at www.yahoogroups.com/list/boost. +
++
+