diff --git a/doc/config.qbk b/doc/config.qbk index c7b1116b9..6c9aad8c3 100644 --- a/doc/config.qbk +++ b/doc/config.qbk @@ -49,6 +49,7 @@ Distributed under the Boost Software License, Version 1.0. [include configuring_boost.qbk] [include macro_reference.qbk] +[include static_assert.qbk] [include build_time.qbk] [include cstdint.qbk] [include guidelines.qbk] diff --git a/doc/html/boost_config/acknowledgements.html b/doc/html/boost_config/acknowledgements.html index 467472429..bf5564616 100644 --- a/doc/html/boost_config/acknowledgements.html +++ b/doc/html/boost_config/acknowledgements.html @@ -3,7 +3,7 @@ Acknowledgements - + diff --git a/doc/html/boost_config/boost_macro_reference.html b/doc/html/boost_config/boost_macro_reference.html index 077976611..2631ec009 100644 --- a/doc/html/boost_config/boost_macro_reference.html +++ b/doc/html/boost_config/boost_macro_reference.html @@ -3,11 +3,11 @@ Boost Macro Reference - + - + @@ -21,7 +21,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -4224,6 +4224,19 @@

+ + +

+ BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +

+ + +

+ The compiler does not support auto + non-type template parameters. +

+ +
@@ -7321,7 +7334,7 @@

-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_config/build_config.html b/doc/html/boost_config/build_config.html index 889e7631c..85eab0ef5 100644 --- a/doc/html/boost_config/build_config.html +++ b/doc/html/boost_config/build_config.html @@ -3,10 +3,10 @@ Build Time Configuration - + - + @@ -21,7 +21,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -167,7 +167,7 @@


-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_config/cstdint.html b/doc/html/boost_config/cstdint.html index fed216c3b..8c5e1e97c 100644 --- a/doc/html/boost_config/cstdint.html +++ b/doc/html/boost_config/cstdint.html @@ -3,7 +3,7 @@ Standard Integer Types - + diff --git a/doc/html/boost_config/guidelines_for_boost_authors.html b/doc/html/boost_config/guidelines_for_boost_authors.html index 6f2e07739..b5c55db2e 100644 --- a/doc/html/boost_config/guidelines_for_boost_authors.html +++ b/doc/html/boost_config/guidelines_for_boost_authors.html @@ -3,7 +3,7 @@ Guidelines for Boost Authors - + diff --git a/doc/html/boost_config/rationale.html b/doc/html/boost_config/rationale.html index 27db670b8..9de72e3df 100644 --- a/doc/html/boost_config/rationale.html +++ b/doc/html/boost_config/rationale.html @@ -3,7 +3,7 @@ Rationale - + diff --git a/doc/html/boost_config/static_assert.html b/doc/html/boost_config/static_assert.html new file mode 100644 index 000000000..2a12fd473 --- /dev/null +++ b/doc/html/boost_config/static_assert.html @@ -0,0 +1,555 @@ + + + +Compile-time assertions + + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ + +

+ The header <boost/static_assert.hpp> + supplies two macros: +

+
BOOST_STATIC_ASSERT(x)
+BOOST_STATIC_ASSERT_MSG(x, msg)
+
+

+ Both generate a compile time error message if the integral-constant-expression + x is not true. In other words, + they are 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 macros will generate neither + code nor data - and the macros 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. +

+

+ If the C++0x static_assert feature + is available, both macros will use it. For BOOST_STATIC_ASSERT(x), + the error message will be a stringized version of x. + For BOOST_STATIC_ASSERT_MSG(x, + msg), + the error message will be the msg + string. +

+

+ If the C++0x static_assert feature + is not available, BOOST_STATIC_ASSERT_MSG(x, + msg) + will be treated as BOOST_STATIC_ASSERT(x). +

+

+ The material that follows assumes the C++0x static_assert + feature is not available. +

+

+ 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: +

+
+ +

+ 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 <limits>
+#include <boost/static_assert.hpp>
+
+namespace my_conditions {
+
+   BOOST_STATIC_ASSERT(std::numeric_limits<int>::digits >= 32);
+   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. +

+
+
+ +

+ 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>
+
+template <class RandomAccessIterator >
+RandomAccessIterator foo(RandomAccessIterator from,
+                         RandomAccessIterator to)
+{
+   // this template can only be used with
+   // random access iterators...
+   typedef typename std::iterator_traits<
+         RandomAccessIterator >::iterator_category cat;
+   BOOST_STATIC_ASSERT(
+      (boost::is_convertible<
+         cat,
+         const std::random_access_iterator_tag&>::value));
+   //
+   // 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). +

+
+
+ +

+ 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 <limits>
+#include <boost/static_assert.hpp>
+
+template <class UnsignedInt>
+class myclass
+{
+private:
+   BOOST_STATIC_ASSERT_MSG(std::numeric_limits<UnsignedInt>::is_specialized, "myclass can only be specialized for types with numeric_limits support.");
+   BOOST_STATIC_ASSERT_MSG(std::numeric_limits<UnsignedInt>::digits >= 16, "Template argument UnsignedInt must have at least 16 bits precision.")
+   BOOST_STATIC_ASSERT_MSG(std::numeric_limits<UnsignedInt>::is_integer, "Template argument UnsignedInt must be an integer.");
+   BOOST_STATIC_ASSERT_MSG(!std::numeric_limits<UnsignedInt>::is_signed, "Template argument UnsignedInt must not be signed.");
+public:
+   /* details here */
+};
+
+
+
+ +

+ Normally static assertions when used inside a class or function template, + will not be instantiated until the template in which it is used is instantiated. + However, there is one potential problem to watch out for: if the static + assertion is not dependent upon one or more template parameters, then the + compiler is permitted to evaluate the static assertion at the point it + is first seen, irrespective of whether the template is ever instantiated, + for example: +

+
template <class T>
+struct must_not_be_instantiated
+{
+   BOOST_STATIC_ASSERT(false);
+};
+
+

+ Will produce a compiler error with some compilers (for example Intel 8.1 + or gcc 3.4), regardless of whether the template is ever instantiated. A + workaround in cases like this is to force the assertion to be dependent + upon a template parameter: +

+
template <class T>
+struct must_not_be_instantiated
+{
+   // this will be triggered if this type is instantiated
+   BOOST_STATIC_ASSERT(sizeof(T) == 0);
+};
+
+
+
+
+ +

+ 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. +

+
+
+ +
+

Table 1. Test programs provided with static_assert

+
+++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Test Program +

+
+

+ Expected to Compile +

+
+

+ Description +

+
+

+ 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.cpp +

+
+

+ Yes +

+
+

+ Illustrates usage, and should always compile, really just tests + compiler compatibility. +

+
+

+ 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). +

+
+
+
+
+
+ +
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/index.html b/doc/html/index.html index f4f3522dd..713f50fbf 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -3,7 +3,7 @@ Boost.Config - + @@ -92,6 +92,12 @@
Macros for libraries with separate source code
+
Compile-time assertions
+
+
Overview and Tutorial
+
How it works
+
Test Programs
+
Build Time Configuration
Standard Integer Types
diff --git a/doc/html/HTML.manifest b/doc/html/standalone_HTML.manifest similarity index 64% rename from doc/html/HTML.manifest rename to doc/html/standalone_HTML.manifest index 632c78f1c..faa0fa8b7 100644 --- a/doc/html/HTML.manifest +++ b/doc/html/standalone_HTML.manifest @@ -1,5 +1,8 @@ index.html boost_config/boost_macro_reference.html +boost_config/static_assert.html +boost_config/build_config.html +boost_config/cstdint.html boost_config/guidelines_for_boost_authors.html boost_config/rationale.html boost_config/acknowledgements.html diff --git a/doc/static_assert.qbk b/doc/static_assert.qbk new file mode 100644 index 000000000..038e58b82 --- /dev/null +++ b/doc/static_assert.qbk @@ -0,0 +1,234 @@ +[/ + Boost.StaticAssert + + Copyright (c) 2000, 2005 Steve Cleary and John Maddock + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + https://www.boost.org/LICENSE_1_0.txt) +] + +[section:static_assert Compile-time assertions] + +[section:intro Overview and Tutorial] + +The header `` supplies two macros: + + BOOST_STATIC_ASSERT(x) + BOOST_STATIC_ASSERT_MSG(x, msg) + +Both generate a compile time error message if the integral-constant-expression `x` +is not true. In other words, they are 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 macros will generate neither code nor data - and the macros 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. + +If the C++0x `static_assert` feature is available, both macros will use it. +For `BOOST_STATIC_ASSERT(x)`, the error message will be a stringized version of `x`. +For `BOOST_STATIC_ASSERT_MSG(x, msg)`, the error message will be the `msg` string. + +If the C++0x `static_assert` feature is not available, `BOOST_STATIC_ASSERT_MSG(x, msg)` +will be treated as `BOOST_STATIC_ASSERT(x)`. + +The material that follows assumes the C++0x `static_assert` feature is not available. + +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 + +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: + +[section:namespace 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 + #include + #include + #include + + namespace my_conditions { + + BOOST_STATIC_ASSERT(std::numeric_limits::digits >= 32); + 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. + +[endsect] + +[section:function 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 + #include + #include + + template + RandomAccessIterator foo(RandomAccessIterator from, + RandomAccessIterator to) + { + // this template can only be used with + // random access iterators... + typedef typename std::iterator_traits< + RandomAccessIterator >::iterator_category cat; + BOOST_STATIC_ASSERT( + (boost::is_convertible< + cat, + const std::random_access_iterator_tag&>::value)); + // + // 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). + +[endsect] + +[section:class 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 + #include + + template + class myclass + { + private: + BOOST_STATIC_ASSERT_MSG(std::numeric_limits::is_specialized, "myclass can only be specialized for types with numeric_limits support."); + BOOST_STATIC_ASSERT_MSG(std::numeric_limits::digits >= 16, "Template argument UnsignedInt must have at least 16 bits precision.") + BOOST_STATIC_ASSERT_MSG(std::numeric_limits::is_integer, "Template argument UnsignedInt must be an integer."); + BOOST_STATIC_ASSERT_MSG(!std::numeric_limits::is_signed, "Template argument UnsignedInt must not be signed."); + public: + /* details here */ + }; + +[endsect] + +[section:templates Use in templates] + +Normally static assertions when used inside a class or function template, +will not be instantiated until the template in which it is used is instantiated. +However, there is one potential problem to watch out for: if the static assertion +is not dependent upon one or more template parameters, then the compiler is +permitted to evaluate the static assertion at the point it is first seen, +irrespective of whether the template is ever instantiated, for example: + + template + struct must_not_be_instantiated + { + BOOST_STATIC_ASSERT(false); + }; + +Will produce a compiler error with some compilers (for example Intel 8.1 +or gcc 3.4), regardless of whether the template is ever instantiated. A +workaround in cases like this is to force the assertion to be dependent +upon a template parameter: + + template + struct must_not_be_instantiated + { + // this will be triggered if this type is instantiated + BOOST_STATIC_ASSERT(sizeof(T) == 0); + }; + + +[endsect] + +[endsect] + +[section:how How it works] + +`BOOST_STATIC_ASSERT` works as follows. There is class `STATIC_ASSERTION_FAILURE` +which is defined as: + + namespace boost{ + + template struct STATIC_ASSERTION_FAILURE; + + template <> struct STATIC_ASSERTION_FAILURE{}; + + } + +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. + +[endsect] + +[section:test Test Programs] + +[table Test programs provided with static_assert +[[Test Program][Expected to Compile][Description]] + +[[[@../../example/static_assert_example_1.cpp static_assert_example_1.cpp]] [Platform dependent.] [Namespace scope test program, may compile depending upon the platform. ]] +[[[@../../example/static_assert_example_2.cpp static_assert_example_2.cpp]] [Yes] [Function scope test program. ]] +[[[@../../example/static_assert_example_3.cpp static_assert_example_3.cpp]] [Yes] [Class scope test program. ]] +[[[@../../test/static_assert_test.cpp static_assert_test.cpp]] [Yes] [Illustrates usage, and should always compile, really just tests compiler compatibility.]] +[[[@../../test/static_assert_test_fail_1.cpp static_assert_test_fail_1.cpp]] [No] [Illustrates failure at namespace scope. ]] +[[[@../../test/static_assert_test_fail_2.cpp static_assert_test_fail_2.cpp]] [No] [Illustrates failure at non-template function scope. ]] +[[[@../../test/static_assert_test_fail_3.cpp static_assert_test_fail_3.cpp]] [No] [Illustrates failure at non-template class scope. ]] +[[[@../../test/static_assert_test_fail_4.cpp static_assert_test_fail_4.cpp]] [No] [Illustrates failure at non-template class scope. ]] +[[[@../../test/static_assert_test_fail_5.cpp static_assert_test_fail_5.cpp]] [No] [Illustrates failure at template class scope. ]] +[[[@../../test/static_assert_test_fail_6.cpp static_assert_test_fail_6.cpp]] [No] [Illustrates failure at template class member function scope. ]] +[[[@../../test/static_assert_test_fail_7.cpp static_assert_test_fail_7.cpp]] [No] [Illustrates failure of class scope example. ]] +[[[@../../test/static_assert_test_fail_8.cpp static_assert_test_fail_8.cpp]] [No] [Illustrates failure of function scope example. ]] +[[[@../../test/static_assert_test_fail_9.cpp static_assert_test_fail_9.cpp]] [No] [Illustrates failure of function scope example (part 2). ]] + +] + +[endsect] + +[endsect] diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 000000000..5f04797a1 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright 2018, 2019 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt + +include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) + +if(HAVE_BOOST_TEST) + +boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::config Boost::type_traits) + +endif() diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 new file mode 100644 index 000000000..6dd1c88c0 --- /dev/null +++ b/example/Jamfile.v2 @@ -0,0 +1,16 @@ +# copyright John Maddock 2003 +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# bring in the rules for testing +import testing ; + +project : requirements + /boost/config//boost_config + /boost/type_traits//boost_type_traits + ; + +#run static_assert_example_1.cpp ; +run static_assert_example_2.cpp ; +run static_assert_example_3.cpp ; diff --git a/example/static_assert_example_1.cpp b/example/static_assert_example_1.cpp new file mode 100644 index 000000000..130625c9d --- /dev/null +++ b/example/static_assert_example_1.cpp @@ -0,0 +1,30 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include +#include +#include + +#if !defined(WCHAR_MIN) +#define WCHAR_MIN 0 +#endif + +namespace boost{ + +namespace my_conditions { +BOOST_STATIC_ASSERT(std::numeric_limits::digits >= 32); +BOOST_STATIC_ASSERT(WCHAR_MIN >= 0); + +} // namespace my_conditions + +} // namespace boost + +int main() +{ + return 0; +} diff --git a/example/static_assert_example_2.cpp b/example/static_assert_example_2.cpp new file mode 100644 index 000000000..adbf32d80 --- /dev/null +++ b/example/static_assert_example_2.cpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include +#include +#include +#include + +template +RandomAccessIterator foo(RandomAccessIterator from, RandomAccessIterator /*to*/) +{ + // this template can only be used with + // random access iterators... + typedef typename std::iterator_traits< RandomAccessIterator >::iterator_category cat; + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + // + // detail goes here... + return from; +} + +int main() +{ + std::deque d; + std::list l; + foo(d.begin(), d.end()); // OK + //foo(l.begin(), l.end()); // error + return 0; +} diff --git a/example/static_assert_example_3.cpp b/example/static_assert_example_3.cpp new file mode 100644 index 000000000..2586e33b1 --- /dev/null +++ b/example/static_assert_example_3.cpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include +#include + +template +class myclass +{ +private: + BOOST_STATIC_ASSERT((std::numeric_limits::digits >= 16) + && std::numeric_limits::is_specialized + && std::numeric_limits::is_integer + && !std::numeric_limits::is_signed); +public: + /* details here */ +}; + +myclass m1; // this should be OK +//myclass m2; // this should fail +//myclass m3; // and so should this + +int main() +{ + return 0; +} diff --git a/include/boost/static_assert.hpp b/include/boost/static_assert.hpp new file mode 100644 index 000000000..5aef6c638 --- /dev/null +++ b/include/boost/static_assert.hpp @@ -0,0 +1,179 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/static_assert for documentation. + +/* + Revision history: + 02 August 2000 + Initial version. +*/ + +#ifndef BOOST_STATIC_ASSERT_HPP +#define BOOST_STATIC_ASSERT_HPP + +#include +#include +#include //for std::size_t + +#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) +// +// This is horrible, but it seems to be the only we can shut up the +// "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]" +// warning that get spewed out otherwise in non-C++11 mode. +// +#pragma GCC system_header +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT_MSG( B, Msg ) static_assert( B, Msg ) +# endif +#else +# define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B ) +#endif + +#ifdef BOOST_BORLANDC +// +// workaround for buggy integral-constant expression support: +#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS +#endif + +#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) +// gcc 3.3 and 3.4 don't produce good error messages with the default version: +# define BOOST_SA_GCC_WORKAROUND +#endif + +// +// If the compiler issues warnings about old C style casts, +// then enable this: +// +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) != 0) +# else +# define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) != 0) +# endif +#else +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x) +# endif +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT( B ) static_assert(B, #B) +# endif +#else + +namespace boost{ + +// HP aCC cannot deal with missing names for template value parameters +template struct STATIC_ASSERTION_FAILURE; + +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; + +// HP aCC cannot deal with missing names for template value parameters +template struct static_assert_test{}; + +} + +// +// Implicit instantiation requires that all member declarations be +// instantiated, but that the definitions are *not* instantiated. +// +// It's not particularly clear how this applies to enum's or typedefs; +// both are described as declarations [7.1.3] and [7.2] in the standard, +// however some compilers use "delayed evaluation" of one or more of +// these when implicitly instantiating templates. We use typedef declarations +// by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum +// version gets better results from your compiler... +// +// Implementation: +// Both of these versions rely on sizeof(incomplete_type) generating an error +// message containing the name of the incomplete type. We use +// "STATIC_ASSERTION_FAILURE" as the type name here to generate +// an eye catching error message. The result of the sizeof expression is either +// used as an enum initialiser, or as a template argument depending which version +// is in use... +// Note that the argument to the assert is explicitly cast to bool using old- +// style casts: too many compilers currently have problems with static_cast +// when used inside integral constant expressions. +// +#if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) + +#if defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) +#define BOOST_STATIC_ASSERT( B ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) +#elif defined(BOOST_MSVC) +#define BOOST_STATIC_ASSERT(...) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) +#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) +// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error +// instead of warning in case of failure +# define BOOST_STATIC_ASSERT( B ) \ + typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ] +#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && !defined(BOOST_NO_CXX11_VARIADIC_MACROS) +// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error +// instead of warning in case of failure +# define BOOST_STATIC_ASSERT(...) \ + typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ] +#elif defined(__sgi) +// special version for SGI MIPSpro compiler +#define BOOST_STATIC_ASSERT( B ) \ + BOOST_STATIC_CONSTANT(bool, \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) +#elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003) +// special version for CodeWarrior <= 8.x +#define BOOST_STATIC_ASSERT( B ) \ + BOOST_STATIC_CONSTANT(int, \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) ) +#else +// generic version +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +# else +# define BOOST_STATIC_ASSERT( B ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +# endif +#endif + +#else +// alternative enum based implementation: +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) \ + enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ + = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) } +# else +# define BOOST_STATIC_ASSERT(B) \ + enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ + = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } +# endif +#endif +#endif // defined(BOOST_NO_CXX11_STATIC_ASSERT) + +#endif // BOOST_STATIC_ASSERT_HPP diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fa4bdbd7b..260cd6ae0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -118,6 +118,20 @@ test-suite config [ compile header_deprecated_test.cpp ] [ compile symbol_deprecated_test.cpp ] [ compile boost_override_test.cpp ] + + [ run static_assert_test.cpp ] + [ compile-fail static_assert_test_fail_1.cpp ] + [ compile-fail static_assert_test_fail_2.cpp ] + [ compile-fail static_assert_test_fail_3.cpp ] + [ compile-fail static_assert_test_fail_4.cpp ] + [ compile-fail static_assert_test_fail_5.cpp ] + [ compile-fail static_assert_test_fail_6.cpp ] + [ compile-fail static_assert_test_fail_7.cpp ] + [ compile-fail static_assert_test_fail_8.cpp ] + [ compile-fail static_assert_test_fail_9.cpp ] + [ compile-fail static_assert_test_fail_10.cpp ] + + [ build-project ../example ] ; obj has_clang_implicit_fallthrough : cmd_line_check.cpp : diff --git a/test/static_assert_test.cpp b/test/static_assert_test.cpp new file mode 100644 index 000000000..6427f88de --- /dev/null +++ b/test/static_assert_test.cpp @@ -0,0 +1,103 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include + +// +// all these tests should succeed. +// some of these tests are rather simplistic (ie useless) +// in order to ensure that they compile on all platforms. +// + +// Namespace scope +BOOST_STATIC_ASSERT(sizeof(int) >= sizeof(short)); +BOOST_STATIC_ASSERT(sizeof(char) == 1); +BOOST_STATIC_ASSERT_MSG(sizeof(int) >= sizeof(short), "msg1"); +BOOST_STATIC_ASSERT_MSG(sizeof(char) == 1, "msg2"); + +// Function (block) scope +void f() +{ + BOOST_STATIC_ASSERT(sizeof(int) >= sizeof(short)); + BOOST_STATIC_ASSERT(sizeof(char) == 1); + BOOST_STATIC_ASSERT_MSG(sizeof(int) >= sizeof(short), "msg3"); + BOOST_STATIC_ASSERT_MSG(sizeof(char) == 1, "msg4"); +} + +struct Bob +{ + private: // can be in private, to avoid namespace pollution + BOOST_STATIC_ASSERT(sizeof(int) >= sizeof(short)); + BOOST_STATIC_ASSERT(sizeof(char) == 1); + BOOST_STATIC_ASSERT_MSG(sizeof(int) >= sizeof(short), "msg5"); + BOOST_STATIC_ASSERT_MSG(sizeof(char) == 1, "msg6"); + public: + + // Member function scope: provides access to member variables + int x; + char c; + int f() + { +#if defined(_MSC_VER) && _MSC_VER < 1300 // broken sizeof in VC6 + BOOST_STATIC_ASSERT(sizeof(x) >= sizeof(short)); + BOOST_STATIC_ASSERT(sizeof(c) == 1); + BOOST_STATIC_ASSERT_MSG(sizeof(x) >= sizeof(short), "msg7"); + BOOST_STATIC_ASSERT_MSG(sizeof(c) == 1, "msg8"); +#endif + return x; + } +}; + + + +// Template class scope +template +struct Bill +{ + BOOST_STATIC_CONSTANT(int, value = 1); + private: // can be in private, to avoid namespace pollution + BOOST_STATIC_ASSERT(sizeof(Int) > sizeof(char)); + BOOST_STATIC_ASSERT_MSG(sizeof(Int) > sizeof(char), "msg9"); + public: + + // Template member function scope: provides access to member variables + Int x; + Char c; + template + void f(Int2 , Char2 ) + { + BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Int2)); + BOOST_STATIC_ASSERT(sizeof(Char) == sizeof(Char2)); + BOOST_STATIC_ASSERT_MSG(sizeof(Int) == sizeof(Int2), "msg10"); + BOOST_STATIC_ASSERT_MSG(sizeof(Char) == sizeof(Char2), "msg11"); + } +}; + +void test_Bill() // BOOST_STATIC_ASSERTs are not triggerred until instantiated +{ + Bill z; + //Bill bad; // will not compile + int i = 3; + char ch = 'a'; + z.f(i, ch); + //z.f(i, i); // should not compile +} + +int main() +{ + test_Bill(); + // + // Test variadic macro support: + // +#ifndef BOOST_NO_CXX11_VARIADIC_MACROS + BOOST_STATIC_ASSERT(Bill::value); +#ifndef BOOST_NO_CXX11_STATIC_ASSERT + BOOST_STATIC_ASSERT_MSG(Bill::value, "This is a message"); +#endif +#endif + return 0; +} diff --git a/test/static_assert_test_fail_1.cpp b/test/static_assert_test_fail_1.cpp new file mode 100644 index 000000000..b0ae6a8bd --- /dev/null +++ b/test/static_assert_test_fail_1.cpp @@ -0,0 +1,17 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include + +// +// all these tests should fail: +// +typedef char a1[2]; +typedef char a2[3]; + +// Namespace scope +BOOST_STATIC_ASSERT(sizeof(a1) == sizeof(a2)); // will not compile diff --git a/test/static_assert_test_fail_10.cpp b/test/static_assert_test_fail_10.cpp new file mode 100644 index 000000000..83649bc78 --- /dev/null +++ b/test/static_assert_test_fail_10.cpp @@ -0,0 +1,18 @@ +//~ Copyright 2005 Redshift Software, Inc. +//~ Distributed under the Boost Software License, Version 1.0. +//~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#include + +template +int foo() +{ + BOOST_STATIC_ASSERT( N < 2 ); + + return N; +} + +int main() +{ + return foo<5>(); +} diff --git a/test/static_assert_test_fail_2.cpp b/test/static_assert_test_fail_2.cpp new file mode 100644 index 000000000..a70ed027a --- /dev/null +++ b/test/static_assert_test_fail_2.cpp @@ -0,0 +1,20 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include + +// +// all these tests should fail: +// +typedef char a1[2]; +typedef char a2[3]; + +// Function (block) scope +void f() +{ + BOOST_STATIC_ASSERT(sizeof(a1) == sizeof(a2)); // should not compile +} diff --git a/test/static_assert_test_fail_3.cpp b/test/static_assert_test_fail_3.cpp new file mode 100644 index 000000000..2eddc5923 --- /dev/null +++ b/test/static_assert_test_fail_3.cpp @@ -0,0 +1,33 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include + +// +// this tests should fail: +// +typedef char a1[2]; +typedef char a2[3]; + +struct Bob +{ + private: // can be in private, to avoid namespace pollution + BOOST_STATIC_ASSERT(sizeof(a1) == sizeof(a2)); // will not compile + public: + + // Member function scope: provides access to member variables + int x; + char c; + int f() + { +#ifndef _MSC_VER // broken sizeof in VC6 + BOOST_STATIC_ASSERT(sizeof(x) == 4); + BOOST_STATIC_ASSERT(sizeof(c) == 1); +#endif + return x; + } +}; diff --git a/test/static_assert_test_fail_4.cpp b/test/static_assert_test_fail_4.cpp new file mode 100644 index 000000000..6a1551a36 --- /dev/null +++ b/test/static_assert_test_fail_4.cpp @@ -0,0 +1,32 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include + +// +// all these tests should fail: +// + + +struct Bob +{ + public: + + // Member function scope: provides access to member variables + char x[4]; + char c; + int f() + { +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // broken sizeof in VC6 + BOOST_STATIC_ASSERT(sizeof(x) == 4); + BOOST_STATIC_ASSERT(sizeof(c) == 1); + BOOST_STATIC_ASSERT((sizeof(x) == sizeof(c))); // should not compile +#endif + return x; + } +}; diff --git a/test/static_assert_test_fail_5.cpp b/test/static_assert_test_fail_5.cpp new file mode 100644 index 000000000..c330080eb --- /dev/null +++ b/test/static_assert_test_fail_5.cpp @@ -0,0 +1,35 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include + +// +// all these tests should fail: +// + +// Template class scope +template +struct Bill +{ + private: // can be in private, to avoid namespace pollution + BOOST_STATIC_ASSERT(sizeof(Int) == 4); + BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Char)); // should not compile when instantiated + public: + + // Template member function scope: provides access to member variables + Int x; + Char c; + template + void f(Int2 , Char2 ) + { + BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Int2)); + BOOST_STATIC_ASSERT(sizeof(Char) == sizeof(Char2)); + //BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Char)); // should not compile when instantiated + } +}; + +Bill b; diff --git a/test/static_assert_test_fail_6.cpp b/test/static_assert_test_fail_6.cpp new file mode 100644 index 000000000..396626299 --- /dev/null +++ b/test/static_assert_test_fail_6.cpp @@ -0,0 +1,42 @@ +// (C) Copyright Steve Cleary & John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include + +// +// all these tests should fail: +// + +// Template class scope +template +struct Bill +{ + private: // can be in private, to avoid namespace pollution + BOOST_STATIC_ASSERT(sizeof(Int) == 4); + //BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Char)); // should not compile when instantiated + public: + + // Template member function scope: provides access to member variables + Int x; + Char c; + template + void f(Int2 , Char2 ) + { + BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Int2)); + BOOST_STATIC_ASSERT(sizeof(Char) == sizeof(Char2)); + BOOST_STATIC_ASSERT(sizeof(Int) == sizeof(Char)); // should not compile when instantiated + } +}; + +void foo() +{ + int i = 0; + char c = 0; + Bill b; + // this should fail: + b.f(i, c); +} diff --git a/test/static_assert_test_fail_7.cpp b/test/static_assert_test_fail_7.cpp new file mode 100644 index 000000000..9ca75baf7 --- /dev/null +++ b/test/static_assert_test_fail_7.cpp @@ -0,0 +1,30 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include +#include + +template +class myclass +{ +private: + BOOST_STATIC_ASSERT(sizeof(UnsignedInt) * CHAR_BIT >= 16); + BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized + && std::numeric_limits::is_integer + && !std::numeric_limits::is_signed); +public: + /* details here */ +}; + +myclass m2; // this should fail +myclass m3; // and so should this + +int main() +{ + return 0; +} diff --git a/test/static_assert_test_fail_8.cpp b/test/static_assert_test_fail_8.cpp new file mode 100644 index 000000000..1099c97c1 --- /dev/null +++ b/test/static_assert_test_fail_8.cpp @@ -0,0 +1,39 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include +#include +#include +#include + +template +RandomAccessIterator foo(RandomAccessIterator from, RandomAccessIterator) +{ + // this template can only be used with + // random access iterators... + typedef typename std::iterator_traits< RandomAccessIterator >::iterator_category cat; + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + // + // detail goes here... + return from; +} + +// ensure that delayed instantiation compilers like Comeau see the failure early +// enough for "compile-fail" testing with the Boost.Build testing framework. (Greg Comeau) +template +std::list::iterator + foo(std::list::iterator, std::list::iterator); + +int main() +{ + std::deque d; + std::list l; + foo(d.begin(), d.end()); // OK + foo(l.begin(), l.end()); // error + return 0; +} diff --git a/test/static_assert_test_fail_9.cpp b/test/static_assert_test_fail_9.cpp new file mode 100644 index 000000000..7cf2fa1ad --- /dev/null +++ b/test/static_assert_test_fail_9.cpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include +#include +#include + +template +class myclass +{ +private: + BOOST_STATIC_ASSERT(sizeof(UnsignedInt) * CHAR_BIT >= 16); + BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized + && std::numeric_limits::is_integer + && !std::numeric_limits::is_signed); +public: + /* details here */ +}; + +myclass m1; // this should be OK +//myclass m2; // this should fail +myclass m3; // and so should this + +int main() +{ + return 0; +}