]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <html> |
2 | <head> | |
3 | <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> | |
4 | <title>Operator Type Traits</title> | |
5 | <link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> | |
6 | <meta name="generator" content="DocBook XSL Stylesheets V1.77.1"> | |
7 | <link rel="home" href="../../../index.html" title="Chapter 1. Boost.TypeTraits"> | |
8 | <link rel="up" href="../value_traits.html" title="Type Traits that Describe the Properties of a Type"> | |
9 | <link rel="prev" href="relate.html" title="Relationships Between Two Types"> | |
10 | <link rel="next" href="../transform.html" title="Type Traits that Transform One Type to Another"> | |
11 | </head> | |
12 | <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> | |
13 | <table cellpadding="2" width="100%"><tr> | |
14 | <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> | |
15 | <td align="center"><a href="../../../../../../../index.html">Home</a></td> | |
16 | <td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> | |
17 | <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> | |
18 | <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> | |
19 | <td align="center"><a href="../../../../../../../more/index.htm">More</a></td> | |
20 | </tr></table> | |
21 | <hr> | |
22 | <div class="spirit-nav"> | |
23 | <a accesskey="p" href="relate.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../value_traits.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="../transform.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> | |
24 | </div> | |
25 | <div class="section"> | |
26 | <div class="titlepage"><div><div><h4 class="title"> | |
27 | <a name="boost_typetraits.category.value_traits.operators"></a><a class="link" href="operators.html" title="Operator Type Traits">Operator | |
28 | Type Traits</a> | |
29 | </h4></div></div></div> | |
30 | <h6> | |
31 | <a name="boost_typetraits.category.value_traits.operators.h0"></a> | |
32 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.introduction"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.introduction">Introduction</a> | |
33 | </h6> | |
34 | <p> | |
35 | These traits are all <span class="emphasis"><em>value traits</em></span> inheriting from | |
36 | <a class="link" href="../../reference/integral_constant.html" title="integral_constant">integral_constant</a> | |
37 | and providing a simple <code class="computeroutput"><span class="keyword">true</span></code> | |
38 | or <code class="computeroutput"><span class="keyword">false</span></code> boolean <code class="computeroutput"><span class="identifier">value</span></code> which reflects the fact that given | |
39 | types can or cannot be used with given operators. | |
40 | </p> | |
41 | <p> | |
42 | For example, <code class="computeroutput"><span class="identifier">has_plus</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>::</span><span class="identifier">value</span></code> | |
43 | is a <code class="computeroutput"><span class="keyword">bool</span></code> which value is | |
44 | <code class="computeroutput"><span class="keyword">true</span></code> because it is possible | |
45 | to add a <code class="computeroutput"><span class="keyword">double</span></code> to an <code class="computeroutput"><span class="keyword">int</span></code> like in the following code: | |
46 | </p> | |
47 | <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> | |
48 | <span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span> | |
49 | <span class="identifier">i</span><span class="special">+</span><span class="identifier">d</span><span class="special">;</span> | |
50 | </pre> | |
51 | <p> | |
52 | It is also possible to know if the result of the operator can be used as | |
53 | function argument of a given type. For example, <code class="computeroutput"><span class="identifier">has_plus</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">float</span><span class="special">>::</span><span class="identifier">value</span></code> | |
54 | is <code class="computeroutput"><span class="keyword">true</span></code> because it is possible | |
55 | to add a <code class="computeroutput"><span class="keyword">double</span></code> to an <code class="computeroutput"><span class="keyword">int</span></code> and the result (<code class="computeroutput"><span class="keyword">double</span></code>) | |
56 | can be converted to a <code class="computeroutput"><span class="keyword">float</span></code> | |
57 | argument like in the following code: | |
58 | </p> | |
59 | <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">float</span><span class="special">)</span> <span class="special">{</span> <span class="special">};</span> | |
60 | <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> | |
61 | <span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span> | |
62 | <span class="identifier">f</span><span class="special">(</span><span class="identifier">i</span><span class="special">+</span><span class="identifier">d</span><span class="special">);</span> | |
63 | </pre> | |
64 | <p> | |
65 | </p> | |
66 | <h6> | |
67 | <a name="boost_typetraits.category.value_traits.operators.h1"></a> | |
68 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.example_of_application"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.example_of_application">Example | |
69 | of application</a> | |
70 | </h6> | |
71 | <p> | |
72 | These traits can be useful to optimize the code for types supporting given | |
73 | operations. For example a function <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">advance</span></code> | |
74 | that increases an iterator of a given number of steps could be implemented | |
75 | as follows: | |
76 | </p> | |
77 | <p> | |
78 | </p> | |
79 | <pre class="programlisting"><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">has_plus_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> | |
80 | ||
81 | <span class="keyword">namespace</span> <span class="identifier">detail</span> <span class="special">{</span> | |
82 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">has_plus_assign</span> <span class="special">></span> | |
83 | <span class="keyword">struct</span> <span class="identifier">advance_impl</span><span class="special">;</span> | |
84 | ||
85 | <span class="comment">// this is used if += exists (efficient)</span> | |
86 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span> <span class="special">></span> | |
87 | <span class="keyword">struct</span> <span class="identifier">advance_impl</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="keyword">true</span><span class="special">></span> <span class="special">{</span> | |
88 | <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Iterator</span> <span class="special">&</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">Distance</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> | |
89 | <span class="identifier">i</span><span class="special">+=</span><span class="identifier">n</span><span class="special">;</span> | |
90 | <span class="special">}</span> | |
91 | <span class="special">};</span> | |
92 | ||
93 | <span class="comment">// this is use if += does not exists (less efficient but cannot do better)</span> | |
94 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span> <span class="special">></span> | |
95 | <span class="keyword">struct</span> <span class="identifier">advance_impl</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="keyword">false</span><span class="special">></span> <span class="special">{</span> | |
96 | <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Iterator</span> <span class="special">&</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">Distance</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> | |
97 | <span class="keyword">if</span> <span class="special">(</span><span class="identifier">n</span><span class="special">></span><span class="number">0</span><span class="special">)</span> <span class="special">{</span> | |
98 | <span class="keyword">while</span> <span class="special">(</span><span class="identifier">n</span><span class="special">--)</span> <span class="special">++</span><span class="identifier">i</span><span class="special">;</span> | |
99 | <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span> | |
100 | <span class="keyword">while</span> <span class="special">(</span><span class="identifier">n</span><span class="special">++)</span> <span class="special">--</span><span class="identifier">i</span><span class="special">;</span> | |
101 | <span class="special">}</span> | |
102 | <span class="special">}</span> | |
103 | <span class="special">};</span> | |
104 | <span class="special">}</span> <span class="comment">// namespace detail</span> | |
105 | ||
106 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span> <span class="special">></span> | |
107 | <span class="keyword">inline</span> <span class="keyword">void</span> <span class="identifier">advance</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="special">&</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">Distance</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> | |
108 | <span class="identifier">detail</span><span class="special">::</span><span class="identifier">advance_impl</span><span class="special"><</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">>()(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span> | |
109 | <span class="special">}</span> | |
110 | </pre> | |
111 | <p> | |
112 | </p> | |
113 | <p> | |
114 | Then the compiler chooses the most efficient implementation according to | |
115 | the type's ability to perform <code class="computeroutput"><span class="special">+=</span></code> | |
116 | operation: | |
117 | </p> | |
118 | <p> | |
119 | </p> | |
120 | <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> | |
121 | ||
122 | <span class="keyword">class</span> <span class="identifier">with</span> <span class="special">{</span> | |
123 | <span class="keyword">int</span> <span class="identifier">m_i</span><span class="special">;</span> | |
124 | <span class="keyword">public</span><span class="special">:</span> | |
125 | <span class="identifier">with</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_i</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span> | |
126 | <span class="identifier">with</span> <span class="special">&</span><span class="keyword">operator</span><span class="special">+=(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">m_i</span><span class="special">+=</span><span class="identifier">rhs</span><span class="special">;</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span> | |
127 | <span class="keyword">operator</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_i</span><span class="special">;</span> <span class="special">}</span> | |
128 | <span class="special">};</span> | |
129 | ||
130 | <span class="keyword">class</span> <span class="identifier">without</span> <span class="special">{</span> | |
131 | <span class="keyword">int</span> <span class="identifier">m_i</span><span class="special">;</span> | |
132 | <span class="keyword">public</span><span class="special">:</span> | |
133 | <span class="identifier">without</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_i</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span> | |
134 | <span class="identifier">without</span> <span class="special">&</span><span class="keyword">operator</span><span class="special">++()</span> <span class="special">{</span> <span class="special">++</span><span class="identifier">m_i</span><span class="special">;</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span> | |
135 | <span class="identifier">without</span> <span class="special">&</span><span class="keyword">operator</span><span class="special">--()</span> <span class="special">{</span> <span class="special">--</span><span class="identifier">m_i</span><span class="special">;</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span> | |
136 | <span class="keyword">operator</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_i</span><span class="special">;</span> <span class="special">}</span> | |
137 | <span class="special">};</span> | |
138 | ||
139 | <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> | |
140 | <span class="identifier">with</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> | |
141 | <span class="identifier">advance</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span> <span class="comment">// uses +=</span> | |
142 | <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="string">"with: "</span><span class="special"><<</span><span class="identifier">i</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> | |
143 | <span class="identifier">without</span> <span class="identifier">j</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> | |
144 | <span class="identifier">advance</span><span class="special">(</span><span class="identifier">j</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span> <span class="comment">// uses ++</span> | |
145 | <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="string">"without: "</span><span class="special"><<</span><span class="identifier">j</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> | |
146 | <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> | |
147 | <span class="special">}</span> | |
148 | </pre> | |
149 | <p> | |
150 | </p> | |
151 | <h6> | |
152 | <a name="boost_typetraits.category.value_traits.operators.h2"></a> | |
153 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.description"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.description">Description</a> | |
154 | </h6> | |
155 | <p> | |
156 | The syntax is the following: | |
157 | </p> | |
158 | <pre class="programlisting"><span class="keyword">template</span> <code class="computeroutput"><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">></span></code> <span class="identifier">has_op</span><span class="special">;</span> <span class="comment">// prefix operator</span> | |
159 | <span class="keyword">template</span> <code class="computeroutput"><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">></span></code> <span class="identifier">has_op</span><span class="special">;</span> <span class="comment">// postfix operator</span> | |
160 | <span class="keyword">template</span> <code class="computeroutput"><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Rhs</span><span class="special">=</span><span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">></span></code> <span class="identifier">has_op</span><span class="special">;</span> <span class="comment">// binary operator</span> | |
161 | </pre> | |
162 | <p> | |
163 | where: | |
164 | </p> | |
165 | <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> | |
166 | <li class="listitem"> | |
167 | op represents the operator name | |
168 | </li> | |
169 | <li class="listitem"> | |
170 | <code class="computeroutput"><span class="identifier">Lhs</span></code> is the type used | |
171 | at the left hand side of <code class="computeroutput"><span class="keyword">operator</span> | |
172 | <span class="identifier">op</span></code>, | |
173 | </li> | |
174 | <li class="listitem"> | |
175 | <code class="computeroutput"><span class="identifier">Rhs</span></code> is the type used | |
176 | at the right hand side of <code class="computeroutput"><span class="keyword">operator</span> | |
177 | <span class="identifier">op</span></code>, | |
178 | </li> | |
179 | <li class="listitem"> | |
180 | <code class="computeroutput"><span class="identifier">Ret</span></code> is the type for | |
181 | which we want to know if the result of <code class="computeroutput"><span class="keyword">operator</span> | |
182 | <span class="identifier">op</span></code> can be converted to. | |
183 | </li> | |
184 | </ul></div> | |
185 | <p> | |
186 | The default behaviour (<code class="computeroutput"><span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span></code>) | |
187 | is to not check for the return value of the operator. If <code class="computeroutput"><span class="identifier">Ret</span></code> is different from the default <code class="computeroutput"><span class="identifier">dont_care</span></code>, the return value is checked | |
188 | to be convertible to <code class="computeroutput"><span class="identifier">Ret</span></code>. | |
189 | Convertible to <code class="computeroutput"><span class="identifier">Ret</span></code> means | |
190 | that the return value can be used as argument to a function expecting | |
191 | <code class="computeroutput"><span class="identifier">Ret</span></code>: | |
192 | </p> | |
193 | <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Ret</span><span class="special">);</span> | |
194 | <span class="identifier">Lhs</span> <span class="identifier">lhs</span><span class="special">;</span> | |
195 | <span class="identifier">Rhs</span> <span class="identifier">rhs</span><span class="special">;</span> | |
196 | <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">+</span><span class="identifier">rhs</span><span class="special">);</span> <span class="comment">// is valid if has_plus<Lhs, Rhs, Ret>::value==true</span> | |
197 | </pre> | |
198 | <p> | |
199 | If <code class="computeroutput"><span class="identifier">Ret</span><span class="special">=</span><span class="keyword">void</span></code>, the return type is checked to be exactly | |
200 | <code class="computeroutput"><span class="keyword">void</span></code>. | |
201 | </p> | |
202 | <p> | |
203 | The following tables give the list of supported binary, prefix and postfix | |
204 | operators. | |
205 | </p> | |
206 | <div class="table"> | |
207 | <a name="boost_typetraits.category.value_traits.operators.supported_prefix_operators"></a><p class="title"><b>Table 1.4. Supported prefix operators</b></p> | |
208 | <div class="table-contents"><table class="table" summary="Supported prefix operators"> | |
209 | <colgroup> | |
210 | <col> | |
211 | <col> | |
212 | </colgroup> | |
213 | <thead><tr> | |
214 | <th> | |
215 | <p> | |
216 | prefix operator | |
217 | </p> | |
218 | </th> | |
219 | <th> | |
220 | <p> | |
221 | trait name | |
222 | </p> | |
223 | </th> | |
224 | </tr></thead> | |
225 | <tbody> | |
226 | <tr> | |
227 | <td> | |
228 | <p> | |
229 | <code class="computeroutput"><span class="special">!</span></code> | |
230 | </p> | |
231 | </td> | |
232 | <td> | |
233 | <p> | |
234 | <a class="link" href="../../reference/has_logical_not.html" title="has_logical_not"><code class="computeroutput"><span class="identifier">has_logical_not</span></code></a> <code class="computeroutput"><span class="special"><</span> <span class="keyword">class</span> | |
235 | <span class="identifier">Rhs</span><span class="special">,</span> | |
236 | <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> | |
237 | <span class="special">></span></code> | |
238 | </p> | |
239 | </td> | |
240 | </tr> | |
241 | <tr> | |
242 | <td> | |
243 | <p> | |
244 | <code class="computeroutput"><span class="special">+</span></code> | |
245 | </p> | |
246 | </td> | |
247 | <td> | |
248 | <p> | |
249 | <a class="link" href="../../reference/has_unary_plus.html" title="has_unary_plus"><code class="computeroutput"><span class="identifier">has_unary_plus</span></code></a> | |
250 | </p> | |
251 | </td> | |
252 | </tr> | |
253 | <tr> | |
254 | <td> | |
255 | <p> | |
256 | <code class="computeroutput"><span class="special">-</span></code> | |
257 | </p> | |
258 | </td> | |
259 | <td> | |
260 | <p> | |
261 | <a class="link" href="../../reference/has_unary_minus.html" title="has_unary_minus"><code class="computeroutput"><span class="identifier">has_unary_minus</span></code></a> and | |
262 | <a class="link" href="../../reference/has_negate.html" title="has_negate"><code class="computeroutput"><span class="identifier">has_negate</span></code></a> | |
263 | </p> | |
264 | </td> | |
265 | </tr> | |
266 | <tr> | |
267 | <td> | |
268 | <p> | |
269 | <code class="computeroutput"><span class="special">~</span></code> | |
270 | </p> | |
271 | </td> | |
272 | <td> | |
273 | <p> | |
274 | <a class="link" href="../../reference/has_complement.html" title="has_complement"><code class="computeroutput"><span class="identifier">has_complement</span></code></a> | |
275 | </p> | |
276 | </td> | |
277 | </tr> | |
278 | <tr> | |
279 | <td> | |
280 | <p> | |
281 | <code class="computeroutput"><span class="special">*</span></code> | |
282 | </p> | |
283 | </td> | |
284 | <td> | |
285 | <p> | |
286 | <a class="link" href="../../reference/has_dereference.html" title="has_dereference"><code class="computeroutput"><span class="identifier">has_dereference</span></code></a> | |
287 | </p> | |
288 | </td> | |
289 | </tr> | |
290 | <tr> | |
291 | <td> | |
292 | <p> | |
293 | <code class="computeroutput"><span class="special">++</span></code> | |
294 | </p> | |
295 | </td> | |
296 | <td> | |
297 | <p> | |
298 | <a class="link" href="../../reference/has_pre_increment.html" title="has_pre_increment"><code class="computeroutput"><span class="identifier">has_pre_increment</span></code></a> | |
299 | </p> | |
300 | </td> | |
301 | </tr> | |
302 | <tr> | |
303 | <td> | |
304 | <p> | |
305 | <code class="computeroutput"><span class="special">--</span></code> | |
306 | </p> | |
307 | </td> | |
308 | <td> | |
309 | <p> | |
310 | <a class="link" href="../../reference/has_pre_decrement.html" title="has_pre_decrement"><code class="computeroutput"><span class="identifier">has_pre_decrement</span></code></a> | |
311 | </p> | |
312 | </td> | |
313 | </tr> | |
314 | </tbody> | |
315 | </table></div> | |
316 | </div> | |
317 | <br class="table-break"><div class="table"> | |
318 | <a name="boost_typetraits.category.value_traits.operators.supported_postfix_operators"></a><p class="title"><b>Table 1.5. Supported postfix operators</b></p> | |
319 | <div class="table-contents"><table class="table" summary="Supported postfix operators"> | |
320 | <colgroup> | |
321 | <col> | |
322 | <col> | |
323 | </colgroup> | |
324 | <thead><tr> | |
325 | <th> | |
326 | <p> | |
327 | postfix operator | |
328 | </p> | |
329 | </th> | |
330 | <th> | |
331 | <p> | |
332 | trait name | |
333 | </p> | |
334 | </th> | |
335 | </tr></thead> | |
336 | <tbody> | |
337 | <tr> | |
338 | <td> | |
339 | <p> | |
340 | <code class="computeroutput"><span class="special">++</span></code> | |
341 | </p> | |
342 | </td> | |
343 | <td> | |
344 | <p> | |
345 | <a class="link" href="../../reference/has_post_increment.html" title="has_post_increment"><code class="computeroutput"><span class="identifier">has_post_increment</span></code></a> | |
346 | <code class="computeroutput"><span class="special"><</span> <span class="keyword">class</span> | |
347 | <span class="identifier">Lhs</span><span class="special">,</span> | |
348 | <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> | |
349 | <span class="special">></span></code> | |
350 | </p> | |
351 | </td> | |
352 | </tr> | |
353 | <tr> | |
354 | <td> | |
355 | <p> | |
356 | <code class="computeroutput"><span class="special">--</span></code> | |
357 | </p> | |
358 | </td> | |
359 | <td> | |
360 | <p> | |
361 | <a class="link" href="../../reference/has_post_decrement.html" title="has_post_decrement"><code class="computeroutput"><span class="identifier">has_post_decrement</span></code></a> | |
362 | </p> | |
363 | </td> | |
364 | </tr> | |
365 | </tbody> | |
366 | </table></div> | |
367 | </div> | |
368 | <br class="table-break"><div class="table"> | |
369 | <a name="boost_typetraits.category.value_traits.operators.supported_binary_operators"></a><p class="title"><b>Table 1.6. Supported binary operators</b></p> | |
370 | <div class="table-contents"><table class="table" summary="Supported binary operators"> | |
371 | <colgroup> | |
372 | <col> | |
373 | <col> | |
374 | </colgroup> | |
375 | <thead><tr> | |
376 | <th> | |
377 | <p> | |
378 | binary operator | |
379 | </p> | |
380 | </th> | |
381 | <th> | |
382 | <p> | |
383 | trait name | |
384 | </p> | |
385 | </th> | |
386 | </tr></thead> | |
387 | <tbody> | |
388 | <tr> | |
389 | <td> | |
390 | <p> | |
391 | <code class="computeroutput"><span class="special">+</span></code> | |
392 | </p> | |
393 | </td> | |
394 | <td> | |
395 | <p> | |
396 | <a class="link" href="../../reference/has_plus.html" title="has_plus"><code class="computeroutput"><span class="identifier">has_plus</span></code></a> <code class="computeroutput"><span class="special"><</span> <span class="keyword">class</span> | |
397 | <span class="identifier">Lhs</span><span class="special">,</span> | |
398 | <span class="keyword">class</span> <span class="identifier">Rhs</span><span class="special">=</span><span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> | |
399 | <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">></span></code> | |
400 | </p> | |
401 | </td> | |
402 | </tr> | |
403 | <tr> | |
404 | <td> | |
405 | <p> | |
406 | <code class="computeroutput"><span class="special">-</span></code> | |
407 | </p> | |
408 | </td> | |
409 | <td> | |
410 | <p> | |
411 | <a class="link" href="../../reference/has_minus.html" title="has_minus"><code class="computeroutput"><span class="identifier">has_minus</span></code></a> | |
412 | </p> | |
413 | </td> | |
414 | </tr> | |
415 | <tr> | |
416 | <td> | |
417 | <p> | |
418 | <code class="computeroutput"><span class="special">*</span></code> | |
419 | </p> | |
420 | </td> | |
421 | <td> | |
422 | <p> | |
423 | <a class="link" href="../../reference/has_multiplies.html" title="has_multiplies"><code class="computeroutput"><span class="identifier">has_multiplies</span></code></a> | |
424 | </p> | |
425 | </td> | |
426 | </tr> | |
427 | <tr> | |
428 | <td> | |
429 | <p> | |
430 | <code class="computeroutput"><span class="special">/</span></code> | |
431 | </p> | |
432 | </td> | |
433 | <td> | |
434 | <p> | |
435 | <a class="link" href="../../reference/has_divides.html" title="has_divides"><code class="computeroutput"><span class="identifier">has_divides</span></code></a> | |
436 | </p> | |
437 | </td> | |
438 | </tr> | |
439 | <tr> | |
440 | <td> | |
441 | <p> | |
442 | <code class="computeroutput"><span class="special">%</span></code> | |
443 | </p> | |
444 | </td> | |
445 | <td> | |
446 | <p> | |
447 | <a class="link" href="../../reference/has_modulus.html" title="has_modulus"><code class="computeroutput"><span class="identifier">has_modulus</span></code></a> | |
448 | </p> | |
449 | </td> | |
450 | </tr> | |
451 | <tr> | |
452 | <td> | |
453 | <p> | |
454 | <code class="computeroutput"><span class="special">+=</span></code> | |
455 | </p> | |
456 | </td> | |
457 | <td> | |
458 | <p> | |
459 | <a class="link" href="../../reference/has_plus_assign.html" title="has_plus_assign"><code class="computeroutput"><span class="identifier">has_plus_assign</span></code></a> | |
460 | </p> | |
461 | </td> | |
462 | </tr> | |
463 | <tr> | |
464 | <td> | |
465 | <p> | |
466 | <code class="computeroutput"><span class="special">-=</span></code> | |
467 | </p> | |
468 | </td> | |
469 | <td> | |
470 | <p> | |
471 | <a class="link" href="../../reference/has_minus_assign.html" title="has_minus_assign"><code class="computeroutput"><span class="identifier">has_minus_assign</span></code></a> | |
472 | </p> | |
473 | </td> | |
474 | </tr> | |
475 | <tr> | |
476 | <td> | |
477 | <p> | |
478 | <code class="computeroutput"><span class="special">*=</span></code> | |
479 | </p> | |
480 | </td> | |
481 | <td> | |
482 | <p> | |
483 | <a class="link" href="../../reference/has_multiplies_assign.html" title="has_multiplies_assign"><code class="computeroutput"><span class="identifier">has_multiplies_assign</span></code></a> | |
484 | </p> | |
485 | </td> | |
486 | </tr> | |
487 | <tr> | |
488 | <td> | |
489 | <p> | |
490 | <code class="computeroutput"><span class="special">/=</span></code> | |
491 | </p> | |
492 | </td> | |
493 | <td> | |
494 | <p> | |
495 | <a class="link" href="../../reference/has_divides_assign.html" title="has_divides_assign"><code class="computeroutput"><span class="identifier">has_divides_assign</span></code></a> | |
496 | </p> | |
497 | </td> | |
498 | </tr> | |
499 | <tr> | |
500 | <td> | |
501 | <p> | |
502 | <code class="computeroutput"><span class="special">%=</span></code> | |
503 | </p> | |
504 | </td> | |
505 | <td> | |
506 | <p> | |
507 | <a class="link" href="../../reference/has_modulus_assign.html" title="has_modulus_assign"><code class="computeroutput"><span class="identifier">has_modulus_assign</span></code></a> | |
508 | </p> | |
509 | </td> | |
510 | </tr> | |
511 | <tr> | |
512 | <td> | |
513 | <p> | |
514 | <code class="computeroutput"><span class="special">&</span></code> | |
515 | </p> | |
516 | </td> | |
517 | <td> | |
518 | <p> | |
519 | <a class="link" href="../../reference/has_bit_and.html" title="has_bit_and"><code class="computeroutput"><span class="identifier">has_bit_and</span></code></a> | |
520 | </p> | |
521 | </td> | |
522 | </tr> | |
523 | <tr> | |
524 | <td> | |
525 | <p> | |
526 | <code class="computeroutput"><span class="special">|</span></code> | |
527 | </p> | |
528 | </td> | |
529 | <td> | |
530 | <p> | |
531 | <a class="link" href="../../reference/has_bit_or.html" title="has_bit_or"><code class="computeroutput"><span class="identifier">has_bit_or</span></code></a> | |
532 | </p> | |
533 | </td> | |
534 | </tr> | |
535 | <tr> | |
536 | <td> | |
537 | <p> | |
538 | <code class="computeroutput"><span class="special">^</span></code> | |
539 | </p> | |
540 | </td> | |
541 | <td> | |
542 | <p> | |
543 | <a class="link" href="../../reference/has_bit_xor.html" title="has_bit_xor"><code class="computeroutput"><span class="identifier">has_bit_xor</span></code></a> | |
544 | </p> | |
545 | </td> | |
546 | </tr> | |
547 | <tr> | |
548 | <td> | |
549 | <p> | |
550 | <code class="computeroutput"><span class="special">&=</span></code> | |
551 | </p> | |
552 | </td> | |
553 | <td> | |
554 | <p> | |
555 | <a class="link" href="../../reference/has_bit_and_assign.html" title="has_bit_and_assign"><code class="computeroutput"><span class="identifier">has_bit_and_assign</span></code></a> | |
556 | </p> | |
557 | </td> | |
558 | </tr> | |
559 | <tr> | |
560 | <td> | |
561 | <p> | |
562 | <code class="computeroutput"><span class="special">|=</span></code> | |
563 | </p> | |
564 | </td> | |
565 | <td> | |
566 | <p> | |
567 | <a class="link" href="../../reference/has_bit_or_assign.html" title="has_bit_or_assign"><code class="computeroutput"><span class="identifier">has_bit_or_assign</span></code></a> | |
568 | </p> | |
569 | </td> | |
570 | </tr> | |
571 | <tr> | |
572 | <td> | |
573 | <p> | |
574 | <code class="computeroutput"><span class="special">^=</span></code> | |
575 | </p> | |
576 | </td> | |
577 | <td> | |
578 | <p> | |
579 | <a class="link" href="../../reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><code class="computeroutput"><span class="identifier">has_bit_xor_assign</span></code></a> | |
580 | </p> | |
581 | </td> | |
582 | </tr> | |
583 | <tr> | |
584 | <td> | |
585 | <p> | |
586 | <code class="computeroutput"><span class="special"><<</span></code> | |
587 | </p> | |
588 | </td> | |
589 | <td> | |
590 | <p> | |
591 | <a class="link" href="../../reference/has_left_shift.html" title="has_left_shift"><code class="computeroutput"><span class="identifier">has_left_shift</span></code></a> | |
592 | </p> | |
593 | </td> | |
594 | </tr> | |
595 | <tr> | |
596 | <td> | |
597 | <p> | |
598 | <code class="computeroutput"><span class="special">>></span></code> | |
599 | </p> | |
600 | </td> | |
601 | <td> | |
602 | <p> | |
603 | <a class="link" href="../../reference/has_right_shift.html" title="has_right_shift"><code class="computeroutput"><span class="identifier">has_right_shift</span></code></a> | |
604 | </p> | |
605 | </td> | |
606 | </tr> | |
607 | <tr> | |
608 | <td> | |
609 | <p> | |
610 | <code class="computeroutput"><span class="special"><<=</span></code> | |
611 | </p> | |
612 | </td> | |
613 | <td> | |
614 | <p> | |
615 | <a class="link" href="../../reference/has_left_shift_assign.html" title="has_left_shift_assign"><code class="computeroutput"><span class="identifier">has_left_shift_assign</span></code></a> | |
616 | </p> | |
617 | </td> | |
618 | </tr> | |
619 | <tr> | |
620 | <td> | |
621 | <p> | |
622 | <code class="computeroutput"><span class="special">>>=</span></code> | |
623 | </p> | |
624 | </td> | |
625 | <td> | |
626 | <p> | |
627 | <a class="link" href="../../reference/has_right_shift_assign.html" title="has_right_shift_assign"><code class="computeroutput"><span class="identifier">has_right_shift_assign</span></code></a> | |
628 | </p> | |
629 | </td> | |
630 | </tr> | |
631 | <tr> | |
632 | <td> | |
633 | <p> | |
634 | <code class="computeroutput"><span class="special">==</span></code> | |
635 | </p> | |
636 | </td> | |
637 | <td> | |
638 | <p> | |
639 | <a class="link" href="../../reference/has_equal_to.html" title="has_equal_to"><code class="computeroutput"><span class="identifier">has_equal_to</span></code></a> | |
640 | </p> | |
641 | </td> | |
642 | </tr> | |
643 | <tr> | |
644 | <td> | |
645 | <p> | |
646 | <code class="computeroutput"><span class="special">!=</span></code> | |
647 | </p> | |
648 | </td> | |
649 | <td> | |
650 | <p> | |
651 | <a class="link" href="../../reference/has_not_equal_to.html" title="has_not_equal_to"><code class="computeroutput"><span class="identifier">has_not_equal_to</span></code></a> | |
652 | </p> | |
653 | </td> | |
654 | </tr> | |
655 | <tr> | |
656 | <td> | |
657 | <p> | |
658 | <code class="computeroutput"><span class="special"><</span></code> | |
659 | </p> | |
660 | </td> | |
661 | <td> | |
662 | <p> | |
663 | <a class="link" href="../../reference/has_less.html" title="has_less"><code class="computeroutput"><span class="identifier">has_less</span></code></a> | |
664 | </p> | |
665 | </td> | |
666 | </tr> | |
667 | <tr> | |
668 | <td> | |
669 | <p> | |
670 | <code class="computeroutput"><span class="special"><=</span></code> | |
671 | </p> | |
672 | </td> | |
673 | <td> | |
674 | <p> | |
675 | <a class="link" href="../../reference/has_less_equal.html" title="has_less_equal"><code class="computeroutput"><span class="identifier">has_less_equal</span></code></a> | |
676 | </p> | |
677 | </td> | |
678 | </tr> | |
679 | <tr> | |
680 | <td> | |
681 | <p> | |
682 | <code class="computeroutput"><span class="special">></span></code> | |
683 | </p> | |
684 | </td> | |
685 | <td> | |
686 | <p> | |
687 | <a class="link" href="../../reference/has_greater.html" title="has_greater"><code class="computeroutput"><span class="identifier">has_greater</span></code></a> | |
688 | </p> | |
689 | </td> | |
690 | </tr> | |
691 | <tr> | |
692 | <td> | |
693 | <p> | |
694 | <code class="computeroutput"><span class="special">>=</span></code> | |
695 | </p> | |
696 | </td> | |
697 | <td> | |
698 | <p> | |
699 | <a class="link" href="../../reference/has_greater_equal.html" title="has_greater_equal"><code class="computeroutput"><span class="identifier">has_greater_equal</span></code></a> | |
700 | </p> | |
701 | </td> | |
702 | </tr> | |
703 | <tr> | |
704 | <td> | |
705 | <p> | |
706 | <code class="computeroutput"><span class="special">&&</span></code> | |
707 | </p> | |
708 | </td> | |
709 | <td> | |
710 | <p> | |
711 | <a class="link" href="../../reference/has_logical_and.html" title="has_logical_and"><code class="computeroutput"><span class="identifier">has_logical_and</span></code></a> | |
712 | </p> | |
713 | </td> | |
714 | </tr> | |
715 | <tr> | |
716 | <td> | |
717 | <p> | |
718 | <code class="computeroutput"><span class="special">||</span></code> | |
719 | </p> | |
720 | </td> | |
721 | <td> | |
722 | <p> | |
723 | <a class="link" href="../../reference/has_logical_or.html" title="has_logical_or"><code class="computeroutput"><span class="identifier">has_logical_or</span></code></a> | |
724 | </p> | |
725 | </td> | |
726 | </tr> | |
727 | </tbody> | |
728 | </table></div> | |
729 | </div> | |
730 | <br class="table-break"><p> | |
731 | The following operators are not supported because they could not be implemented | |
732 | using the same technique: <code class="computeroutput"><span class="keyword">operator</span><span class="special">=</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">,</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">operator</span> | |
733 | <span class="keyword">new</span></code>. | |
734 | </p> | |
735 | <h6> | |
736 | <a name="boost_typetraits.category.value_traits.operators.h3"></a> | |
737 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.cv_qualifiers_and_references"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.cv_qualifiers_and_references">cv | |
738 | qualifiers and references</a> | |
739 | </h6> | |
740 | <p> | |
741 | A reference sign <code class="computeroutput"><span class="special">&</span></code> in | |
742 | the operator argument is ignored so that <code class="computeroutput"><span class="identifier">has_plus</span><span class="special"><</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">double</span><span class="special">&</span> <span class="special">>::</span><span class="identifier">value</span><span class="special">==</span><span class="identifier">has_plus</span><span class="special"><</span> | |
743 | <span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">>::</span><span class="identifier">value</span></code>. This has been chosen because if | |
744 | the following code works (does not work): | |
745 | </p> | |
746 | <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> | |
747 | <span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span> | |
748 | <span class="identifier">i</span><span class="special">+</span><span class="identifier">d</span><span class="special">;</span> | |
749 | </pre> | |
750 | <p> | |
751 | the following code also works (does not work): | |
752 | </p> | |
753 | <pre class="programlisting"><span class="keyword">int</span> <span class="special">&</span><span class="identifier">ir</span><span class="special">=</span><span class="identifier">i</span><span class="special">;</span> | |
754 | <span class="keyword">double</span> <span class="special">&</span><span class="identifier">dr</span><span class="special">=</span><span class="identifier">d</span><span class="special">;</span> | |
755 | <span class="identifier">ir</span><span class="special">+</span><span class="identifier">dr</span><span class="special">;</span> | |
756 | </pre> | |
757 | <p> | |
758 | </p> | |
759 | <p> | |
760 | It was not possible to handle properly the <code class="computeroutput"><span class="keyword">volatile</span></code> | |
761 | qualifier so that any construct using this qualifier has undefined behavior. | |
762 | </p> | |
763 | <p> | |
764 | As a help, the following tables give the necessary conditions over each | |
765 | trait template argument for the trait <code class="computeroutput"><span class="identifier">value</span></code> | |
766 | to be <code class="computeroutput"><span class="keyword">true</span></code>. They are non sufficient | |
767 | conditions because the conditions must be <code class="computeroutput"><span class="keyword">true</span></code> | |
768 | for all arguments and return type for <code class="computeroutput"><span class="identifier">value</span></code> | |
769 | to be <code class="computeroutput"><span class="keyword">true</span></code>. | |
770 | </p> | |
771 | <div class="table"> | |
772 | <a name="boost_typetraits.category.value_traits.operators.necessary_and_non_sufficient_condition_on_operator_argument_for_value_to_be_true"></a><p class="title"><b>Table 1.7. necessary and non sufficient condition on operator argument for | |
773 | value to be true</b></p> | |
774 | <div class="table-contents"><table class="table" summary="necessary and non sufficient condition on operator argument for | |
775 | value to be true"> | |
776 | <colgroup> | |
777 | <col> | |
778 | <col> | |
779 | <col> | |
780 | <col> | |
781 | </colgroup> | |
782 | <thead><tr> | |
783 | <th> | |
784 | <p> | |
785 | operator declaration | |
786 | </p> | |
787 | </th> | |
788 | <th> | |
789 | <p> | |
790 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
791 | <span class="keyword">void</span> <span class="special">></span></code> | |
792 | </p> | |
793 | </th> | |
794 | <th> | |
795 | <p> | |
796 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
797 | <span class="identifier">Arg</span> <span class="special">></span></code> | |
798 | and <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
799 | <span class="identifier">Arg</span><span class="special">&</span> | |
800 | <span class="special">></span></code> | |
801 | </p> | |
802 | </th> | |
803 | <th> | |
804 | <p> | |
805 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
806 | <span class="identifier">Arg</span> <span class="keyword">const</span> | |
807 | <span class="special">></span></code> and <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
808 | <span class="identifier">Arg</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">></span></code> | |
809 | </p> | |
810 | </th> | |
811 | </tr></thead> | |
812 | <tbody> | |
813 | <tr> | |
814 | <td> | |
815 | <p> | |
816 | <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span><span class="special">)</span></code> | |
817 | </p> | |
818 | </td> | |
819 | <td> | |
820 | <p> | |
821 | false | |
822 | </p> | |
823 | </td> | |
824 | <td> | |
825 | <p> | |
826 | true | |
827 | </p> | |
828 | </td> | |
829 | <td> | |
830 | <p> | |
831 | true | |
832 | </p> | |
833 | </td> | |
834 | </tr> | |
835 | <tr> | |
836 | <td> | |
837 | <p> | |
838 | <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span> | |
839 | <span class="keyword">const</span><span class="special">)</span></code> | |
840 | </p> | |
841 | </td> | |
842 | <td> | |
843 | <p> | |
844 | false | |
845 | </p> | |
846 | </td> | |
847 | <td> | |
848 | <p> | |
849 | true | |
850 | </p> | |
851 | </td> | |
852 | <td> | |
853 | <p> | |
854 | true | |
855 | </p> | |
856 | </td> | |
857 | </tr> | |
858 | <tr> | |
859 | <td> | |
860 | <p> | |
861 | <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span> | |
862 | <span class="special">&)</span></code> | |
863 | </p> | |
864 | </td> | |
865 | <td> | |
866 | <p> | |
867 | false | |
868 | </p> | |
869 | </td> | |
870 | <td> | |
871 | <p> | |
872 | true | |
873 | </p> | |
874 | </td> | |
875 | <td> | |
876 | <p> | |
877 | false | |
878 | </p> | |
879 | </td> | |
880 | </tr> | |
881 | <tr> | |
882 | <td> | |
883 | <p> | |
884 | <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span> | |
885 | <span class="keyword">const</span> <span class="special">&)</span></code> | |
886 | </p> | |
887 | </td> | |
888 | <td> | |
889 | <p> | |
890 | false | |
891 | </p> | |
892 | </td> | |
893 | <td> | |
894 | <p> | |
895 | true | |
896 | </p> | |
897 | </td> | |
898 | <td> | |
899 | <p> | |
900 | true | |
901 | </p> | |
902 | </td> | |
903 | </tr> | |
904 | </tbody> | |
905 | </table></div> | |
906 | </div> | |
907 | <br class="table-break"><div class="table"> | |
908 | <a name="boost_typetraits.category.value_traits.operators.necessary_and_non_sufficient_condition_on_operator_return_type_for_value_to_be_true"></a><p class="title"><b>Table 1.8. necessary and non sufficient condition on operator return type for | |
909 | value to be true</b></p> | |
910 | <div class="table-contents"><table class="table" summary="necessary and non sufficient condition on operator return type for | |
911 | value to be true"> | |
912 | <colgroup> | |
913 | <col> | |
914 | <col> | |
915 | <col> | |
916 | <col> | |
917 | <col> | |
918 | <col> | |
919 | </colgroup> | |
920 | <thead><tr> | |
921 | <th> | |
922 | <p> | |
923 | operator declaration | |
924 | </p> | |
925 | </th> | |
926 | <th> | |
927 | <p> | |
928 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
929 | <span class="special">...,</span> <span class="keyword">void</span> | |
930 | <span class="special">></span></code> | |
931 | </p> | |
932 | </th> | |
933 | <th> | |
934 | <p> | |
935 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
936 | <span class="special">...,</span> <span class="identifier">Ret</span> | |
937 | <span class="special">></span></code> | |
938 | </p> | |
939 | </th> | |
940 | <th> | |
941 | <p> | |
942 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
943 | <span class="special">...,</span> <span class="identifier">Ret</span> | |
944 | <span class="keyword">const</span> <span class="special">></span></code> | |
945 | </p> | |
946 | </th> | |
947 | <th> | |
948 | <p> | |
949 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
950 | <span class="special">...,</span> <span class="identifier">Ret</span> | |
951 | <span class="special">&</span> <span class="special">></span></code> | |
952 | </p> | |
953 | </th> | |
954 | <th> | |
955 | <p> | |
956 | <code class="computeroutput"><span class="identifier">has_op</span><span class="special"><</span> | |
957 | <span class="special">...,</span> <span class="identifier">Ret</span> | |
958 | <span class="keyword">const</span> <span class="special">&</span> | |
959 | <span class="special">></span></code> | |
960 | </p> | |
961 | </th> | |
962 | </tr></thead> | |
963 | <tbody> | |
964 | <tr> | |
965 | <td> | |
966 | <p> | |
967 | <code class="computeroutput"><span class="keyword">void</span> <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code> | |
968 | </p> | |
969 | </td> | |
970 | <td> | |
971 | <p> | |
972 | true | |
973 | </p> | |
974 | </td> | |
975 | <td> | |
976 | <p> | |
977 | false | |
978 | </p> | |
979 | </td> | |
980 | <td> | |
981 | <p> | |
982 | false | |
983 | </p> | |
984 | </td> | |
985 | <td> | |
986 | <p> | |
987 | false | |
988 | </p> | |
989 | </td> | |
990 | <td> | |
991 | <p> | |
992 | false | |
993 | </p> | |
994 | </td> | |
995 | </tr> | |
996 | <tr> | |
997 | <td> | |
998 | <p> | |
999 | <code class="computeroutput"><span class="identifier">Ret</span> <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code> | |
1000 | </p> | |
1001 | </td> | |
1002 | <td> | |
1003 | <p> | |
1004 | false | |
1005 | </p> | |
1006 | </td> | |
1007 | <td> | |
1008 | <p> | |
1009 | true | |
1010 | </p> | |
1011 | </td> | |
1012 | <td> | |
1013 | <p> | |
1014 | true | |
1015 | </p> | |
1016 | </td> | |
1017 | <td> | |
1018 | <p> | |
1019 | false | |
1020 | </p> | |
1021 | </td> | |
1022 | <td> | |
1023 | <p> | |
1024 | true | |
1025 | </p> | |
1026 | </td> | |
1027 | </tr> | |
1028 | <tr> | |
1029 | <td> | |
1030 | <p> | |
1031 | <code class="computeroutput"><span class="identifier">Ret</span> <span class="keyword">const</span> | |
1032 | <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code> | |
1033 | </p> | |
1034 | </td> | |
1035 | <td> | |
1036 | <p> | |
1037 | false | |
1038 | </p> | |
1039 | </td> | |
1040 | <td> | |
1041 | <p> | |
1042 | true | |
1043 | </p> | |
1044 | </td> | |
1045 | <td> | |
1046 | <p> | |
1047 | true | |
1048 | </p> | |
1049 | </td> | |
1050 | <td> | |
1051 | <p> | |
1052 | false | |
1053 | </p> | |
1054 | </td> | |
1055 | <td> | |
1056 | <p> | |
1057 | true | |
1058 | </p> | |
1059 | </td> | |
1060 | </tr> | |
1061 | <tr> | |
1062 | <td> | |
1063 | <p> | |
1064 | <code class="computeroutput"><span class="identifier">Ret</span> <span class="special">&</span> | |
1065 | <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code> | |
1066 | </p> | |
1067 | </td> | |
1068 | <td> | |
1069 | <p> | |
1070 | false | |
1071 | </p> | |
1072 | </td> | |
1073 | <td> | |
1074 | <p> | |
1075 | true | |
1076 | </p> | |
1077 | </td> | |
1078 | <td> | |
1079 | <p> | |
1080 | true | |
1081 | </p> | |
1082 | </td> | |
1083 | <td> | |
1084 | <p> | |
1085 | true | |
1086 | </p> | |
1087 | </td> | |
1088 | <td> | |
1089 | <p> | |
1090 | true | |
1091 | </p> | |
1092 | </td> | |
1093 | </tr> | |
1094 | <tr> | |
1095 | <td> | |
1096 | <p> | |
1097 | <code class="computeroutput"><span class="identifier">Ret</span> <span class="keyword">const</span> | |
1098 | <span class="special">&</span> <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code> | |
1099 | </p> | |
1100 | </td> | |
1101 | <td> | |
1102 | <p> | |
1103 | false | |
1104 | </p> | |
1105 | </td> | |
1106 | <td> | |
1107 | <p> | |
1108 | true | |
1109 | </p> | |
1110 | </td> | |
1111 | <td> | |
1112 | <p> | |
1113 | true | |
1114 | </p> | |
1115 | </td> | |
1116 | <td> | |
1117 | <p> | |
1118 | false | |
1119 | </p> | |
1120 | </td> | |
1121 | <td> | |
1122 | <p> | |
1123 | true | |
1124 | </p> | |
1125 | </td> | |
1126 | </tr> | |
1127 | </tbody> | |
1128 | </table></div> | |
1129 | </div> | |
1130 | <br class="table-break"><h6> | |
1131 | <a name="boost_typetraits.category.value_traits.operators.h4"></a> | |
1132 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.implementation"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.implementation">Implementation</a> | |
1133 | </h6> | |
1134 | <p> | |
1135 | The implementation consists in only header files. The following headers | |
1136 | should included first: | |
1137 | </p> | |
1138 | <pre class="programlisting"><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">has_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></pre> | |
1139 | <p> | |
1140 | or | |
1141 | </p> | |
1142 | <pre class="programlisting"><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">has_op</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></pre> | |
1143 | <p> | |
1144 | where <code class="literal">op</code> is the textual name chosen for the wanted operator. | |
1145 | The first method includes all operator traits. | |
1146 | </p> | |
1147 | <p> | |
1148 | All traits are implemented the same way using preprocessor macros to avoid | |
1149 | code duplication. The main files are in <code class="literal">boost/type_traits/detail</code>: | |
1150 | <code class="literal">has_binary_operator.hpp</code>, <code class="literal">has_prefix_operator.hpp</code> | |
1151 | and <code class="literal">has_postfix_operator.hpp</code>. The example of prefix | |
1152 | <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code> | |
1153 | is presented below: | |
1154 | </p> | |
1155 | <p> | |
1156 | </p> | |
1157 | <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> | |
1158 | <span class="keyword">namespace</span> <span class="identifier">detail</span> <span class="special">{</span> | |
1159 | ||
1160 | <span class="comment">// This namespace ensures that argument-dependent name lookup does not mess things up.</span> | |
1161 | <span class="keyword">namespace</span> <span class="identifier">has_unary_minus_impl</span> <span class="special">{</span> | |
1162 | ||
1163 | <span class="comment">// 1. a function to have an instance of type T without requiring T to be default</span> | |
1164 | <span class="comment">// constructible</span> | |
1165 | <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> <span class="identifier">T</span> <span class="special">&</span><span class="identifier">make</span><span class="special">();</span> | |
1166 | ||
1167 | ||
1168 | <span class="comment">// 2. we provide our operator definition for types that do not have one already</span> | |
1169 | ||
1170 | <span class="comment">// a type returned from operator- when no such operator is</span> | |
1171 | <span class="comment">// found in the type's own namespace (our own operator is used) so that we have</span> | |
1172 | <span class="comment">// a means to know that our operator was used</span> | |
1173 | <span class="keyword">struct</span> <span class="identifier">no_operator</span> <span class="special">{</span> <span class="special">};</span> | |
1174 | ||
1175 | <span class="comment">// this class allows implicit conversions and makes the following operator</span> | |
1176 | <span class="comment">// definition less-preferred than any other such operators that might be found</span> | |
1177 | <span class="comment">// via argument-dependent name lookup</span> | |
1178 | <span class="keyword">struct</span> <span class="identifier">any</span> <span class="special">{</span> <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="identifier">any</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&);</span> <span class="special">};</span> | |
1179 | ||
1180 | <span class="comment">// when operator- is not available, this one is used</span> | |
1181 | <span class="identifier">no_operator</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">any</span><span class="special">&);</span> | |
1182 | ||
1183 | ||
1184 | <span class="comment">// 3. checks if the operator returns void or not</span> | |
1185 | <span class="comment">// conditions: Rhs!=void</span> | |
1186 | ||
1187 | <span class="comment">// we first redefine "operator," so that we have no compilation error if</span> | |
1188 | <span class="comment">// operator- returns void and we can use the return type of</span> | |
1189 | <span class="comment">// (-rhs, returns_void_t()) to deduce if operator- returns void or not:</span> | |
1190 | <span class="comment">// - operator- returns void -> (-rhs, returns_void_t()) returns returns_void_t</span> | |
1191 | <span class="comment">// - operator- returns !=void -> (-rhs, returns_void_t()) returns int</span> | |
1192 | <span class="keyword">struct</span> <span class="identifier">returns_void_t</span> <span class="special">{</span> <span class="special">};</span> | |
1193 | <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">,(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&,</span> <span class="identifier">returns_void_t</span><span class="special">);</span> | |
1194 | <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">,(</span><span class="keyword">const</span> <span class="keyword">volatile</span> <span class="identifier">T</span><span class="special">&,</span> <span class="identifier">returns_void_t</span><span class="special">);</span> | |
1195 | ||
1196 | <span class="comment">// this intermediate trait has member value of type bool:</span> | |
1197 | <span class="comment">// - value==true -> operator- returns void</span> | |
1198 | <span class="comment">// - value==false -> operator- does not return void</span> | |
1199 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">></span> | |
1200 | <span class="keyword">struct</span> <span class="identifier">operator_returns_void</span> <span class="special">{</span> | |
1201 | <span class="comment">// overloads of function returns_void make the difference</span> | |
1202 | <span class="comment">// yes_type and no_type have different size by construction</span> | |
1203 | <span class="keyword">static</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">yes_type</span> <span class="identifier">returns_void</span><span class="special">(</span><span class="identifier">returns_void_t</span><span class="special">);</span> | |
1204 | <span class="keyword">static</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">no_type</span> <span class="identifier">returns_void</span><span class="special">(</span><span class="keyword">int</span><span class="special">);</span> | |
1205 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">sizeof</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">yes_type</span><span class="special">)==</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">returns_void</span><span class="special">((-</span><span class="identifier">make</span><span class="special"><</span><span class="identifier">Rhs</span><span class="special">>(),</span><span class="identifier">returns_void_t</span><span class="special">())));</span> | |
1206 | <span class="special">};</span> | |
1207 | ||
1208 | ||
1209 | <span class="comment">// 4. checks if the return type is Ret or Ret==dont_care</span> | |
1210 | <span class="comment">// conditions: Rhs!=void</span> | |
1211 | ||
1212 | <span class="keyword">struct</span> <span class="identifier">dont_care</span> <span class="special">{</span> <span class="special">};</span> | |
1213 | ||
1214 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">Returns_void</span> <span class="special">></span> | |
1215 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span><span class="special">;</span> | |
1216 | ||
1217 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">></span> | |
1218 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">dont_care</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">></span> <span class="special">{</span> | |
1219 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> | |
1220 | <span class="special">};</span> | |
1221 | ||
1222 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">></span> | |
1223 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">dont_care</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">></span> <span class="special">{</span> | |
1224 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> | |
1225 | <span class="special">};</span> | |
1226 | ||
1227 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">></span> | |
1228 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">></span> <span class="special">{</span> | |
1229 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> | |
1230 | <span class="special">};</span> | |
1231 | ||
1232 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">></span> | |
1233 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">></span> <span class="special">{</span> | |
1234 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span> | |
1235 | <span class="special">};</span> | |
1236 | ||
1237 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">></span> | |
1238 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">></span> <span class="special">{</span> | |
1239 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span> | |
1240 | <span class="special">};</span> | |
1241 | ||
1242 | <span class="comment">// otherwise checks if it is convertible to Ret using the sizeof trick</span> | |
1243 | <span class="comment">// based on overload resolution</span> | |
1244 | <span class="comment">// condition: Ret!=void and Ret!=dont_care and the operator does not return void</span> | |
1245 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">></span> | |
1246 | <span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">></span> <span class="special">{</span> | |
1247 | <span class="keyword">static</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">yes_type</span> <span class="identifier">is_convertible_to_Ret</span><span class="special">(</span><span class="identifier">Ret</span><span class="special">);</span> <span class="comment">// this version is preferred for types convertible to Ret</span> | |
1248 | <span class="keyword">static</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">no_type</span> <span class="identifier">is_convertible_to_Ret</span><span class="special">(...);</span> <span class="comment">// this version is used otherwise</span> | |
1249 | ||
1250 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">is_convertible_to_Ret</span><span class="special">(-</span><span class="identifier">make</span><span class="special"><</span><span class="identifier">Rhs</span><span class="special">>()))==</span><span class="keyword">sizeof</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">yes_type</span><span class="special">);</span> | |
1251 | <span class="special">};</span> | |
1252 | ||
1253 | ||
1254 | <span class="comment">// 5. checks for operator existence</span> | |
1255 | <span class="comment">// condition: Rhs!=void</span> | |
1256 | ||
1257 | <span class="comment">// checks if our definition of operator- is used or an other</span> | |
1258 | <span class="comment">// existing one;</span> | |
1259 | <span class="comment">// this is done with redefinition of "operator," that returns no_operator or has_operator</span> | |
1260 | <span class="keyword">struct</span> <span class="identifier">has_operator</span> <span class="special">{</span> <span class="special">};</span> | |
1261 | <span class="identifier">no_operator</span> <span class="keyword">operator</span><span class="special">,(</span><span class="identifier">no_operator</span><span class="special">,</span> <span class="identifier">has_operator</span><span class="special">);</span> | |
1262 | ||
1263 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">></span> | |
1264 | <span class="keyword">struct</span> <span class="identifier">operator_exists</span> <span class="special">{</span> | |
1265 | <span class="keyword">static</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">yes_type</span> <span class="identifier">check</span><span class="special">(</span><span class="identifier">has_operator</span><span class="special">);</span> <span class="comment">// this version is preferred when operator exists</span> | |
1266 | <span class="keyword">static</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">no_type</span> <span class="identifier">check</span><span class="special">(</span><span class="identifier">no_operator</span><span class="special">);</span> <span class="comment">// this version is used otherwise</span> | |
1267 | ||
1268 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">check</span><span class="special">(((-</span><span class="identifier">make</span><span class="special"><</span><span class="identifier">Rhs</span><span class="special">>()),</span><span class="identifier">make</span><span class="special"><</span><span class="identifier">has_operator</span><span class="special">>())))==</span><span class="keyword">sizeof</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">yes_type</span><span class="special">);</span> | |
1269 | <span class="special">};</span> | |
1270 | ||
1271 | ||
1272 | <span class="comment">// 6. main trait: to avoid any compilation error, this class behaves</span> | |
1273 | <span class="comment">// differently when operator-(Rhs) is forbidden by the standard.</span> | |
1274 | <span class="comment">// Forbidden_if is a bool that is:</span> | |
1275 | <span class="comment">// - true when the operator-(Rhs) is forbidden by the standard</span> | |
1276 | <span class="comment">// (would yield compilation error if used)</span> | |
1277 | <span class="comment">// - false otherwise</span> | |
1278 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">Forbidden_if</span> <span class="special">></span> | |
1279 | <span class="keyword">struct</span> <span class="identifier">trait_impl1</span><span class="special">;</span> | |
1280 | ||
1281 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">></span> | |
1282 | <span class="keyword">struct</span> <span class="identifier">trait_impl1</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">></span> <span class="special">{</span> | |
1283 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span> | |
1284 | <span class="special">};</span> | |
1285 | ||
1286 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">></span> | |
1287 | <span class="keyword">struct</span> <span class="identifier">trait_impl1</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">></span> <span class="special">{</span> | |
1288 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> | |
1289 | <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">ice_and</span><span class="special"><</span> | |
1290 | <span class="identifier">operator_exists</span> <span class="special"><</span> <span class="identifier">Rhs</span> <span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> | |
1291 | <span class="identifier">operator_returns_Ret</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="identifier">operator_returns_void</span> <span class="special"><</span> <span class="identifier">Rhs</span> <span class="special">>::</span><span class="identifier">value</span> <span class="special">>::</span><span class="identifier">value</span> | |
1292 | <span class="special">>::</span><span class="identifier">value</span> | |
1293 | <span class="special">;</span> | |
1294 | <span class="special">};</span> | |
1295 | ||
1296 | <span class="comment">// specialization needs to be declared for the special void case</span> | |
1297 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">></span> | |
1298 | <span class="keyword">struct</span> <span class="identifier">trait_impl1</span> <span class="special"><</span> <span class="keyword">void</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">></span> <span class="special">{</span> | |
1299 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span> | |
1300 | <span class="special">};</span> | |
1301 | ||
1302 | <span class="comment">// defines some typedef for convenience</span> | |
1303 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">></span> | |
1304 | <span class="keyword">struct</span> <span class="identifier">trait_impl</span> <span class="special">{</span> | |
1305 | <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">Rhs</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">Rhs_noref</span><span class="special">;</span> | |
1306 | <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_cv</span><span class="special"><</span><span class="identifier">Rhs_noref</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">Rhs_nocv</span><span class="special">;</span> | |
1307 | <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_cv</span><span class="special"><</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_pointer</span><span class="special"><</span><span class="identifier">Rhs_noref</span><span class="special">>::</span><span class="identifier">type</span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">Rhs_noptr</span><span class="special">;</span> | |
1308 | <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">trait_impl1</span> <span class="special"><</span> <span class="identifier">Rhs_noref</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_pointer</span><span class="special"><</span> <span class="identifier">Rhs_noref</span> <span class="special">>::</span><span class="identifier">value</span> <span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> | |
1309 | <span class="special">};</span> | |
1310 | ||
1311 | <span class="special">}</span> <span class="comment">// namespace impl</span> | |
1312 | <span class="special">}</span> <span class="comment">// namespace detail</span> | |
1313 | ||
1314 | <span class="comment">// this is the accessible definition of the trait to end user</span> | |
1315 | <span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span><span class="special">=::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">has_unary_minus_impl</span><span class="special">::</span><span class="identifier">dont_care</span> <span class="special">></span> | |
1316 | <span class="keyword">struct</span> <span class="identifier">has_unary_minus</span> <span class="special">:</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">integral_constant</span><span class="special"><</span><span class="keyword">bool</span><span class="special">,(::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">has_unary_minus_impl</span><span class="special">::</span><span class="identifier">trait_impl</span> <span class="special"><</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span> <span class="special">>::</span><span class="identifier">value</span><span class="special">)></span> <span class="special">{</span> <span class="special">};</span> | |
1317 | ||
1318 | <span class="special">}</span> <span class="comment">// namespace boost</span> | |
1319 | </pre> | |
1320 | <p> | |
1321 | </p> | |
1322 | <h6> | |
1323 | <a name="boost_typetraits.category.value_traits.operators.h5"></a> | |
1324 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.limitation"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.limitation">Limitation</a> | |
1325 | </h6> | |
1326 | <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> | |
1327 | Requires a compiler with working SFINAE. | |
1328 | </li></ul></div> | |
1329 | <h6> | |
1330 | <a name="boost_typetraits.category.value_traits.operators.h6"></a> | |
1331 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.known_issues"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.known_issues">Known | |
1332 | issues</a> | |
1333 | </h6> | |
1334 | <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> | |
1335 | <li class="listitem"> | |
1336 | These traits cannot detect whether the operators are public or not: | |
1337 | if an operator is defined as a private member of type <code class="computeroutput"><span class="identifier">T</span></code> then the instantiation of the corresponding | |
1338 | trait will produce a compiler error. For this reason these traits cannot | |
1339 | be used to determine whether a type has a public operator or not. | |
1340 | <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="identifier">A</span> <span class="keyword">operator</span><span class="special">-();</span> <span class="special">};</span> | |
1341 | <span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator-() is private</span> | |
1342 | </pre> | |
1343 | </li> | |
1344 | <li class="listitem"> | |
1345 | There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code> | |
1346 | is convertible to <code class="computeroutput"><span class="identifier">A</span></code>. | |
1347 | In this case, the compiler will report an ambiguous overload because | |
1348 | both the existing operator and the one we provide (with argument of | |
1349 | type <code class="computeroutput"><span class="identifier">any</span></code>) need type | |
1350 | conversion, so that none is preferred. | |
1351 | <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span> | |
1352 | <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> | |
1353 | <span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span> | |
1354 | <span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span> | |
1355 | <span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload between</span> | |
1356 | <span class="comment">// operator-(const any&) and</span> | |
1357 | <span class="comment">// operator-(const A&)</span> | |
1358 | <span class="comment">// both need type conversion</span> | |
1359 | </pre> | |
1360 | <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="special">};</span> | |
1361 | <span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="identifier">A</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">B</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span> <span class="special">};</span> | |
1362 | <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> | |
1363 | <span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span> | |
1364 | <span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload between</span> | |
1365 | <span class="comment">// operator-(const any&) and</span> | |
1366 | <span class="comment">// operator-(const A&)</span> | |
1367 | <span class="comment">// both need type conversion</span> | |
1368 | </pre> | |
1369 | </li> | |
1370 | <li class="listitem"> | |
1371 | There is an issue when applying these traits to template classes. If | |
1372 | the operator is defined but does not bind for a given template type, | |
1373 | it is still detected by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code> | |
1374 | instead of <code class="computeroutput"><span class="keyword">false</span></code>. This | |
1375 | applies in particular to the containers of the standard library and | |
1376 | <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code>. | |
1377 | Example: | |
1378 | <pre class="programlisting"><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">has_equal_to</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> | |
1379 | <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> | |
1380 | ||
1381 | <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> | |
1382 | <span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span> | |
1383 | ||
1384 | <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> | |
1385 | <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span> | |
1386 | <span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span> | |
1387 | <span class="special">}</span> | |
1388 | ||
1389 | <span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span> | |
1390 | <span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span> | |
1391 | <span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span> | |
1392 | ||
1393 | <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> | |
1394 | <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span> | |
1395 | <span class="comment">// works fine for contains<good></span> | |
1396 | <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span> | |
1397 | <span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span> | |
1398 | <span class="identifier">g</span><span class="special">==</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span> | |
1399 | <span class="comment">// does not work for contains<bad></span> | |
1400 | <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span> | |
1401 | <span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span> | |
1402 | <span class="identifier">b</span><span class="special">==</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span> | |
1403 | <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> | |
1404 | <span class="special">}</span> | |
1405 | </pre> | |
1406 | </li> | |
1407 | <li class="listitem"> | |
1408 | <code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is | |
1409 | not properly handled and would lead to undefined behavior | |
1410 | </li> | |
1411 | </ul></div> | |
1412 | <h6> | |
1413 | <a name="boost_typetraits.category.value_traits.operators.h7"></a> | |
1414 | <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.acknowledgments"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.acknowledgments">Acknowledgments</a> | |
1415 | </h6> | |
1416 | <p> | |
1417 | Frederic Bron is very thankful to numerous people from the boost mailing | |
1418 | list for their kind help and patience. In particular, the following persons | |
1419 | have been very helpful for the implementation: Edward Diener, Eric Niebler, | |
1420 | Jeffrey Lee Hellrung (Jr.), Robert Stewart, Roman Perepelitsa, Steven Watanabe, | |
1421 | Vicente Botet. | |
1422 | </p> | |
1423 | </div> | |
1424 | <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> | |
1425 | <td align="left"></td> | |
1426 | <td align="right"><div class="copyright-footer">Copyright © 2000, 2011 Adobe Systems Inc, David Abrahams, | |
1427 | Frederic Bron, Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, | |
1428 | Jesse Jones, Mat Marcus, Itay Maman, John Maddock, Alexander Nasonov, Thorsten | |
1429 | Ottosen, Roman Perepelitsa, Robert Ramey, Jeremy Siek, Robert Stewart and Steven | |
1430 | Watanabe<p> | |
1431 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
1432 | 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>) | |
1433 | </p> | |
1434 | </div></td> | |
1435 | </tr></table> | |
1436 | <hr> | |
1437 | <div class="spirit-nav"> | |
1438 | <a accesskey="p" href="relate.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../value_traits.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="../transform.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> | |
1439 | </div> | |
1440 | </body> | |
1441 | </html> |