mirror of
https://github.com/boostorg/config.git
synced 2026-01-19 04:02:17 +00:00
Merge pull request #531 from Lastique/feature/move_static_assert
Merge Boost.StaticAssert into Boost.Config.
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Acknowledgements</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="rationale.html" title="Rationale">
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Boost Macro Reference</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="../index.html" title="Boost.Config">
|
||||
<link rel="next" href="build_config.html" title="Build Time Configuration">
|
||||
<link rel="next" href="static_assert.html" title="Compile-time assertions">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@@ -21,7 +21,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="build_config.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="static_assert.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@@ -4224,6 +4224,19 @@
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The compiler does not support <code class="computeroutput"><span class="keyword">auto</span></code>
|
||||
non-type template parameters.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
@@ -7321,7 +7334,7 @@
|
||||
</div>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="build_config.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="static_assert.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Build Time Configuration</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="boost_macro_reference.html" title="Boost Macro Reference">
|
||||
<link rel="prev" href="static_assert.html" title="Compile-time assertions">
|
||||
<link rel="next" href="cstdint.html" title="Standard Integer Types">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
@@ -21,7 +21,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="boost_macro_reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cstdint.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="static_assert.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cstdint.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@@ -167,7 +167,7 @@
|
||||
</div>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="boost_macro_reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cstdint.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="static_assert.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cstdint.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Standard Integer Types</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="build_config.html" title="Build Time Configuration">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Guidelines for Boost Authors</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="cstdint.html" title="Standard Integer Types">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Rationale</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="guidelines_for_boost_authors.html" title="Guidelines for Boost Authors">
|
||||
|
||||
555
doc/html/boost_config/static_assert.html
Normal file
555
doc/html/boost_config/static_assert.html
Normal file
@@ -0,0 +1,555 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Compile-time assertions</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="../index.html" title="Boost.Config">
|
||||
<link rel="up" href="../index.html" title="Boost.Config">
|
||||
<link rel="prev" href="boost_macro_reference.html" title="Boost Macro Reference">
|
||||
<link rel="next" href="build_config.html" title="Build Time Configuration">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="boost_macro_reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="build_config.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_config.static_assert"></a><a class="link" href="static_assert.html" title="Compile-time assertions">Compile-time assertions</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.intro">Overview and Tutorial</a></span></dt>
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.how">How it works</a></span></dt>
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.test">Test Programs</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_config.static_assert.intro"></a><a class="link" href="static_assert.html#boost_config.static_assert.intro" title="Overview and Tutorial">Overview and Tutorial</a>
|
||||
</h3></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.intro.namespace">Use at
|
||||
namespace scope</a></span></dt>
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.intro.function">Use at function
|
||||
scope</a></span></dt>
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.intro.class">Use at class
|
||||
scope</a></span></dt>
|
||||
<dt><span class="section"><a href="static_assert.html#boost_config.static_assert.intro.templates">Use in
|
||||
templates</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
The header <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>
|
||||
supplies two macros:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">msg</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
Both generate a compile time error message if the integral-constant-expression
|
||||
<code class="computeroutput"><span class="identifier">x</span></code> 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 <code class="computeroutput"><span class="keyword">true</span></code>, 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.
|
||||
</p>
|
||||
<p>
|
||||
If the C++0x <code class="computeroutput"><span class="keyword">static_assert</span></code> feature
|
||||
is available, both macros will use it. For <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>,
|
||||
the error message will be a stringized version of <code class="computeroutput"><span class="identifier">x</span></code>.
|
||||
For <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span>
|
||||
<span class="identifier">msg</span><span class="special">)</span></code>,
|
||||
the error message will be the <code class="computeroutput"><span class="identifier">msg</span></code>
|
||||
string.
|
||||
</p>
|
||||
<p>
|
||||
If the C++0x <code class="computeroutput"><span class="keyword">static_assert</span></code> feature
|
||||
is not available, <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span>
|
||||
<span class="identifier">msg</span><span class="special">)</span></code>
|
||||
will be treated as <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The material that follows assumes the C++0x <code class="computeroutput"><span class="keyword">static_assert</span></code>
|
||||
feature is not available.
|
||||
</p>
|
||||
<p>
|
||||
One of the aims of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
|
||||
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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">Illegal</span> <span class="identifier">use</span> <span class="identifier">of</span> <span class="identifier">STATIC_ASSERTION_FAILURE</span><span class="special"><</span><span class="keyword">false</span><span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
Which is intended to at least catch the eye!
|
||||
</p>
|
||||
<p>
|
||||
You can use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
|
||||
at any place where you can place a declaration, that is at class, function
|
||||
or namespace scope, this is illustrated by the following examples:
|
||||
</p>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_config.static_assert.intro.namespace"></a><a class="link" href="static_assert.html#boost_config.static_assert.intro.namespace" title="Use at namespace scope">Use at
|
||||
namespace scope</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
be at least a 32-bit integral type, and that <code class="computeroutput"><span class="keyword">wchar_t</span></code>
|
||||
be an unsigned type. We can verify this at compile time as follows:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">climits</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cwchar</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">namespace</span> <span class="identifier">my_conditions</span> <span class="special">{</span>
|
||||
|
||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">>=</span> <span class="number">32</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">WCHAR_MIN</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||||
|
||||
<span class="special">}</span> <span class="comment">// namespace my_conditions</span>
|
||||
</pre>
|
||||
<p>
|
||||
The use of the namespace my_conditions here requires some comment. The
|
||||
macro <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
|
||||
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 <code class="computeroutput"><span class="identifier">__LINE__</span></code>.
|
||||
When <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
|
||||
is used at either class or function scope then each use of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> 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 <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
|
||||
in a header and at namespace scope, then enclose them in a namespace unique
|
||||
to that header.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_config.static_assert.intro.function"></a><a class="link" href="static_assert.html#boost_config.static_assert.intro.function" title="Use at function scope">Use at function
|
||||
scope</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iterator</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">RandomAccessIterator</span> <span class="special">></span>
|
||||
<span class="identifier">RandomAccessIterator</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">from</span><span class="special">,</span>
|
||||
<span class="identifier">RandomAccessIterator</span> <span class="identifier">to</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// this template can only be used with</span>
|
||||
<span class="comment">// random access iterators...</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span>
|
||||
<span class="identifier">RandomAccessIterator</span> <span class="special">>::</span><span class="identifier">iterator_category</span> <span class="identifier">cat</span><span class="special">;</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span>
|
||||
<span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_convertible</span><span class="special"><</span>
|
||||
<span class="identifier">cat</span><span class="special">,</span>
|
||||
<span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">random_access_iterator_tag</span><span class="special">&>::</span><span class="identifier">value</span><span class="special">));</span>
|
||||
<span class="comment">//</span>
|
||||
<span class="comment">// detail goes here...</span>
|
||||
<span class="keyword">return</span> <span class="identifier">from</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
A couple of footnotes are in order here: the extra set of parenthesis around
|
||||
the assert, is to prevent the comma inside the <code class="computeroutput"><span class="identifier">is_convertible</span></code>
|
||||
template being interpreted by the preprocessor as a macro argument separator;
|
||||
the target type for <code class="computeroutput"><span class="identifier">is_convertible</span></code>
|
||||
is a reference type, as some compilers have problems using <code class="computeroutput"><span class="identifier">is_convertible</span></code> when the conversion is
|
||||
via a user defined constructor (in any case there is no guarantee that
|
||||
the iterator tag classes are copy-constructible).
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_config.static_assert.intro.class"></a><a class="link" href="static_assert.html#boost_config.static_assert.intro.class" title="Use at class scope">Use at class
|
||||
scope</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">UnsignedInt</span><span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">myclass</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">private</span><span class="special">:</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">UnsignedInt</span><span class="special">>::</span><span class="identifier">is_specialized</span><span class="special">,</span> <span class="string">"myclass can only be specialized for types with numeric_limits support."</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">UnsignedInt</span><span class="special">>::</span><span class="identifier">digits</span> <span class="special">>=</span> <span class="number">16</span><span class="special">,</span> <span class="string">"Template argument UnsignedInt must have at least 16 bits precision."</span><span class="special">)</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">UnsignedInt</span><span class="special">>::</span><span class="identifier">is_integer</span><span class="special">,</span> <span class="string">"Template argument UnsignedInt must be an integer."</span><span class="special">);</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(!</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">UnsignedInt</span><span class="special">>::</span><span class="identifier">is_signed</span><span class="special">,</span> <span class="string">"Template argument UnsignedInt must not be signed."</span><span class="special">);</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="comment">/* details here */</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_config.static_assert.intro.templates"></a><a class="link" href="static_assert.html#boost_config.static_assert.intro.templates" title="Use in templates">Use in
|
||||
templates</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">must_not_be_instantiated</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">must_not_be_instantiated</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// this will be triggered if this type is instantiated</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_config.static_assert.how"></a><a class="link" href="static_assert.html#boost_config.static_assert.how" title="How it works">How it works</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> works
|
||||
as follows. There is class <code class="computeroutput"><span class="identifier">STATIC_ASSERTION_FAILURE</span></code>
|
||||
which is defined as:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">STATIC_ASSERTION_FAILURE</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><></span> <span class="keyword">struct</span> <span class="identifier">STATIC_ASSERTION_FAILURE</span><span class="special"><</span><span class="keyword">true</span><span class="special">>{};</span>
|
||||
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The key feature is that the error message triggered by the undefined expression
|
||||
<code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">STATIC_ASSERTION_FAILURE</span><span class="special"><</span><span class="number">0</span><span class="special">>)</span></code>, tends
|
||||
to be consistent across a wide variety of compilers. The rest of the machinery
|
||||
of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> is
|
||||
just a way to feed the <code class="computeroutput"><span class="keyword">sizeof</span></code>
|
||||
expression into a <code class="computeroutput"><span class="keyword">typedef</span></code>. 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.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_config.static_assert.test"></a><a class="link" href="static_assert.html#boost_config.static_assert.test" title="Test Programs">Test Programs</a>
|
||||
</h3></div></div></div>
|
||||
<div class="table">
|
||||
<a name="boost_config.static_assert.test.t0"></a><p class="title"><b>Table 1. Test programs provided with static_assert</b></p>
|
||||
<div class="table-contents"><table class="table" summary="Test programs provided with static_assert">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
<p>
|
||||
Test Program
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
Expected to Compile
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
Description
|
||||
</p>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../example/static_assert_example_1.cpp" target="_top">static_assert_example_1.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Platform dependent.
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Namespace scope test program, may compile depending upon the platform.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../example/static_assert_example_2.cpp" target="_top">static_assert_example_2.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Yes
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Function scope test program.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../example/static_assert_example_3.cpp" target="_top">static_assert_example_3.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Yes
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Class scope test program.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test.cpp" target="_top">static_assert_test.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Yes
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates usage, and should always compile, really just tests
|
||||
compiler compatibility.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_1.cpp" target="_top">static_assert_test_fail_1.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure at namespace scope.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_2.cpp" target="_top">static_assert_test_fail_2.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure at non-template function scope.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_3.cpp" target="_top">static_assert_test_fail_3.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure at non-template class scope.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_4.cpp" target="_top">static_assert_test_fail_4.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure at non-template class scope.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_5.cpp" target="_top">static_assert_test_fail_5.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure at template class scope.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_6.cpp" target="_top">static_assert_test_fail_6.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure at template class member function scope.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_7.cpp" target="_top">static_assert_test_fail_7.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure of class scope example.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_8.cpp" target="_top">static_assert_test_fail_8.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure of function scope example.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a href="../../../test/static_assert_test_fail_9.cpp" target="_top">static_assert_test_fail_9.cpp</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
No
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Illustrates failure of function scope example (part 2).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
<br class="table-break">
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright-footer">Copyright © 2001-2007 Beman Dawes, Vesa Karvonen, John
|
||||
Maddock<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="boost_macro_reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="build_config.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Boost.Config</title>
|
||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||||
<link rel="home" href="index.html" title="Boost.Config">
|
||||
<link rel="next" href="boost_config/boost_macro_reference.html" title="Boost Macro Reference">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@@ -92,6 +92,12 @@
|
||||
<dt><span class="section"><a href="boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_for_libraries_with_separate_source_code">Macros
|
||||
for libraries with separate source code</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_config/static_assert.html">Compile-time assertions</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_config/static_assert.html#boost_config.static_assert.intro">Overview and Tutorial</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_config/static_assert.html#boost_config.static_assert.how">How it works</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_config/static_assert.html#boost_config.static_assert.test">Test Programs</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_config/build_config.html">Build Time Configuration</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_config/cstdint.html">Standard Integer Types</a></span></dt>
|
||||
<dd><dl>
|
||||
|
||||
@@ -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
|
||||
234
doc/static_assert.qbk
Normal file
234
doc/static_assert.qbk
Normal file
@@ -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 `<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:
|
||||
|
||||
[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 <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.
|
||||
|
||||
[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 <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).
|
||||
|
||||
[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 <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 */
|
||||
};
|
||||
|
||||
[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 <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);
|
||||
};
|
||||
|
||||
|
||||
[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 <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.
|
||||
|
||||
[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]
|
||||
11
example/CMakeLists.txt
Normal file
11
example/CMakeLists.txt
Normal file
@@ -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()
|
||||
16
example/Jamfile.v2
Normal file
16
example/Jamfile.v2
Normal file
@@ -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
|
||||
<library>/boost/config//boost_config
|
||||
<library>/boost/type_traits//boost_type_traits
|
||||
;
|
||||
|
||||
#run static_assert_example_1.cpp ;
|
||||
run static_assert_example_2.cpp ;
|
||||
run static_assert_example_3.cpp ;
|
||||
30
example/static_assert_example_1.cpp
Normal file
30
example/static_assert_example_1.cpp
Normal file
@@ -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 <climits>
|
||||
#include <cwchar>
|
||||
#include <limits>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#if !defined(WCHAR_MIN)
|
||||
#define WCHAR_MIN 0
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace my_conditions {
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<int>::digits >= 32);
|
||||
BOOST_STATIC_ASSERT(WCHAR_MIN >= 0);
|
||||
|
||||
} // namespace my_conditions
|
||||
|
||||
} // namespace boost
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
33
example/static_assert_example_2.cpp
Normal file
33
example/static_assert_example_2.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::deque<int> d;
|
||||
std::list<int> l;
|
||||
foo(d.begin(), d.end()); // OK
|
||||
//foo(l.begin(), l.end()); // error
|
||||
return 0;
|
||||
}
|
||||
31
example/static_assert_example_3.cpp
Normal file
31
example/static_assert_example_3.cpp
Normal file
@@ -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 <limits>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
template <class UnsignedInt>
|
||||
class myclass
|
||||
{
|
||||
private:
|
||||
BOOST_STATIC_ASSERT((std::numeric_limits<UnsignedInt>::digits >= 16)
|
||||
&& std::numeric_limits<UnsignedInt>::is_specialized
|
||||
&& std::numeric_limits<UnsignedInt>::is_integer
|
||||
&& !std::numeric_limits<UnsignedInt>::is_signed);
|
||||
public:
|
||||
/* details here */
|
||||
};
|
||||
|
||||
myclass<unsigned> m1; // this should be OK
|
||||
//myclass<int> m2; // this should fail
|
||||
//myclass<unsigned char> m3; // and so should this
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
179
include/boost/static_assert.hpp
Normal file
179
include/boost/static_assert.hpp
Normal file
@@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <cstddef> //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 <bool x> struct STATIC_ASSERTION_FAILURE;
|
||||
|
||||
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
||||
|
||||
// HP aCC cannot deal with missing names for template value parameters
|
||||
template<std::size_t x> 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
|
||||
@@ -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 :
|
||||
|
||||
103
test/static_assert_test.cpp
Normal file
103
test/static_assert_test.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// 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 <class Int, class Char>
|
||||
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 <class Int2, class Char2>
|
||||
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<int, char> z;
|
||||
//Bill<int, int> 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<int, char>::value);
|
||||
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
|
||||
BOOST_STATIC_ASSERT_MSG(Bill<int, char>::value, "This is a message");
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
17
test/static_assert_test_fail_1.cpp
Normal file
17
test/static_assert_test_fail_1.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// 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
|
||||
18
test/static_assert_test_fail_10.cpp
Normal file
18
test/static_assert_test_fail_10.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
template <int N>
|
||||
int foo()
|
||||
{
|
||||
BOOST_STATIC_ASSERT( N < 2 );
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo<5>();
|
||||
}
|
||||
20
test/static_assert_test_fail_2.cpp
Normal file
20
test/static_assert_test_fail_2.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// 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
|
||||
}
|
||||
33
test/static_assert_test_fail_3.cpp
Normal file
33
test/static_assert_test_fail_3.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
32
test/static_assert_test_fail_4.cpp
Normal file
32
test/static_assert_test_fail_4.cpp
Normal file
@@ -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 <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
35
test/static_assert_test_fail_5.cpp
Normal file
35
test/static_assert_test_fail_5.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// all these tests should fail:
|
||||
//
|
||||
|
||||
// Template class scope
|
||||
template <class Int, class Char>
|
||||
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 <class Int2, class Char2>
|
||||
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<int, char> b;
|
||||
42
test/static_assert_test_fail_6.cpp
Normal file
42
test/static_assert_test_fail_6.cpp
Normal file
@@ -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 <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// all these tests should fail:
|
||||
//
|
||||
|
||||
// Template class scope
|
||||
template <class Int, class Char>
|
||||
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 <class Int2, class Char2>
|
||||
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<int, char> b;
|
||||
// this should fail:
|
||||
b.f(i, c);
|
||||
}
|
||||
30
test/static_assert_test_fail_7.cpp
Normal file
30
test/static_assert_test_fail_7.cpp
Normal file
@@ -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 <climits>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
template <class UnsignedInt>
|
||||
class myclass
|
||||
{
|
||||
private:
|
||||
BOOST_STATIC_ASSERT(sizeof(UnsignedInt) * CHAR_BIT >= 16);
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<UnsignedInt>::is_specialized
|
||||
&& std::numeric_limits<UnsignedInt>::is_integer
|
||||
&& !std::numeric_limits<UnsignedInt>::is_signed);
|
||||
public:
|
||||
/* details here */
|
||||
};
|
||||
|
||||
myclass<int> m2; // this should fail
|
||||
myclass<unsigned char> m3; // and so should this
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
39
test/static_assert_test_fail_8.cpp
Normal file
39
test/static_assert_test_fail_8.cpp
Normal file
@@ -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 <iterator>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
template <class RandomAccessIterator >
|
||||
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<cat*, std::random_access_iterator_tag*>::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<int>::iterator
|
||||
foo(std::list<int>::iterator, std::list<int>::iterator);
|
||||
|
||||
int main()
|
||||
{
|
||||
std::deque<int> d;
|
||||
std::list<int> l;
|
||||
foo(d.begin(), d.end()); // OK
|
||||
foo(l.begin(), l.end()); // error
|
||||
return 0;
|
||||
}
|
||||
31
test/static_assert_test_fail_9.cpp
Normal file
31
test/static_assert_test_fail_9.cpp
Normal file
@@ -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 <climits>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
template <class UnsignedInt>
|
||||
class myclass
|
||||
{
|
||||
private:
|
||||
BOOST_STATIC_ASSERT(sizeof(UnsignedInt) * CHAR_BIT >= 16);
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<UnsignedInt>::is_specialized
|
||||
&& std::numeric_limits<UnsignedInt>::is_integer
|
||||
&& !std::numeric_limits<UnsignedInt>::is_signed);
|
||||
public:
|
||||
/* details here */
|
||||
};
|
||||
|
||||
myclass<unsigned> m1; // this should be OK
|
||||
//myclass<int> m2; // this should fail
|
||||
myclass<unsigned char> m3; // and so should this
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user