mirror of
https://github.com/boostorg/utility.git
synced 2025-10-06 05:50:54 +02:00
Compare commits
398 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
4af61235b9 | ||
|
d5a5b84a40 | ||
|
35d3c03d19 | ||
|
8933fbb254 | ||
|
c320330cd5 | ||
|
822b46a3df | ||
|
a821ef6e2c | ||
|
491db15997 | ||
|
b6c826a139 | ||
|
7b472a05ee | ||
|
9a07bc0d9b | ||
|
154d6bb198 | ||
|
0dde936e61 | ||
|
918bf25039 | ||
|
04fda4fb4e | ||
|
e14a250d6e | ||
|
806745f24e | ||
|
4231f774e4 | ||
|
dfc320124f | ||
|
be43ba1569 | ||
|
f3f879555a | ||
|
3155044abd | ||
|
484d184de5 | ||
|
3305cf1592 | ||
|
ec36cd8c54 | ||
|
61fb5a0b8f | ||
|
8024c3e9c7 | ||
|
2f5945d0cd | ||
|
929517d6d7 | ||
|
abcab174a5 | ||
|
801be90699 | ||
|
265c2348b8 | ||
|
fb95bcc64c | ||
|
aedc410525 | ||
|
7fa440c154 | ||
|
746e0fad2b | ||
|
1616f6f5a8 | ||
|
ca3e7d8530 | ||
|
f0f753ba6c | ||
|
532065b51b | ||
|
4bfb534bae | ||
|
95ba7a4381 | ||
|
e92213431e | ||
|
7dd7daee1b | ||
|
953cc46220 | ||
|
b5ae0ad86b | ||
|
c86fcbf456 | ||
|
6ded8b9ad6 | ||
|
bb6a6272e1 | ||
|
242634b3fc | ||
|
662cf14bf6 | ||
|
fe3aaf62cd | ||
|
cb189bd6be | ||
|
f57c914b8f | ||
|
7cec198e14 | ||
|
52d3120528 | ||
|
f1aff5670c | ||
|
632f682292 | ||
|
d1d0d6b788 | ||
|
3bd833c8ff | ||
|
1ef77b0853 | ||
|
074007ab8c | ||
|
c4b7aaf281 | ||
|
22b8494e9a | ||
|
c1c8329403 | ||
|
20a89040e1 | ||
|
1c7a2a1476 | ||
|
7c40cc0b63 | ||
|
73a9e0d351 | ||
|
dc9856744a | ||
|
88f4e47550 | ||
|
1be04eeec5 | ||
|
56acf9c325 | ||
|
c6e3957efc | ||
|
25e8284950 | ||
|
37a6537a5b | ||
|
80df1d8f12 | ||
|
75afed7f17 | ||
|
1d7066aee1 | ||
|
12272a38d4 | ||
|
04f901e52e | ||
|
fabfb31bf6 | ||
|
683701cd07 | ||
|
119c64be0b | ||
|
d429c9a7d8 | ||
|
1e8216431b | ||
|
e45b2e2136 | ||
|
9e6951009b | ||
|
a009a209f1 | ||
|
97605056ed | ||
|
8fcfa33d33 | ||
|
aa65e3da3b | ||
|
b4cfadb4d5 | ||
|
45a6249668 | ||
|
1d601aef4d | ||
|
32fb45eba9 | ||
|
2b7d10aceb | ||
|
5dc62711e1 | ||
|
252c02aca0 | ||
|
9655beb7ba | ||
|
f0ea53e77e | ||
|
4755b42909 | ||
|
ef9af03c6c | ||
|
7439073cbf | ||
|
aff985a563 | ||
|
db425222d5 | ||
|
e20af510f7 | ||
|
d8230c6a73 | ||
|
f5690787bf | ||
|
a4fd7b32dd | ||
|
f4336ec693 | ||
|
03d906976b | ||
|
4ba6a96822 | ||
|
1ea4140d56 | ||
|
351d4ecb15 | ||
|
7fbf84dcc6 | ||
|
3ff49b272d | ||
|
5b52e3d418 | ||
|
8c0eb498d3 | ||
|
48a81ef7ea | ||
|
f7610c9b26 | ||
|
1755eaf019 | ||
|
6b8b218efb | ||
|
333d79b345 | ||
|
f0fa436fe4 | ||
|
13e6d78fa8 | ||
|
7126ea2685 | ||
|
a37518cb4a | ||
|
64b3e8c3bd | ||
|
339937380e | ||
|
6156f0d302 | ||
|
00560e8e17 | ||
|
029ff9828f | ||
|
ec188c7c3e | ||
|
0a0296a5d0 | ||
|
6e26a5bbe7 | ||
|
dc1b6246a0 | ||
|
15f69eaf14 | ||
|
4774a0d325 | ||
|
be78ab72c9 | ||
|
0bc4a1b20d | ||
|
c8b674d105 | ||
|
b421d4725a | ||
|
1662bb5713 | ||
|
ad79a21abd | ||
|
19645a52e6 | ||
|
74c3077c9a | ||
|
1f29191329 | ||
|
4b636a7680 | ||
|
e6fc2555f3 | ||
|
e27d0fcf2a | ||
|
2643c33b20 | ||
|
71af1e77c8 | ||
|
99e7406bd9 | ||
|
413265f497 | ||
|
fe44cdf09b | ||
|
e413428d71 | ||
|
88b9822db7 | ||
|
24045c0cd7 | ||
|
d2aa9f4a84 | ||
|
d2a5fd169f | ||
|
4e350d9934 | ||
|
f3f697bbc8 | ||
|
c7c09696db | ||
|
dbcc58d984 | ||
|
8231310c4d | ||
|
2988140430 | ||
|
7387966005 | ||
|
e0a5a61375 | ||
|
66ecd70689 | ||
|
67f4f45653 | ||
|
1bf28b3de2 | ||
|
eb3c3435d7 | ||
|
8a81d8b16c | ||
|
bc9d8b13d0 | ||
|
4768b167ab | ||
|
591ff70ed1 | ||
|
7bf2ad0b22 | ||
|
409c79b2e4 | ||
|
d0410691a1 | ||
|
64e5115138 | ||
|
7ae912d83c | ||
|
2937f5876c | ||
|
8619c9b5c3 | ||
|
e4d5684f6b | ||
|
3d69cf95da | ||
|
18944572b7 | ||
|
3e9d0f80c2 | ||
|
a2c4d1990a | ||
|
404261c6ee | ||
|
87abc59612 | ||
|
cb98ddf7db | ||
|
7d2e6c9025 | ||
|
75eaa14a18 | ||
|
082d6e3b32 | ||
|
35b3770b6f | ||
|
5b9d20c7e2 | ||
|
5bbed2372e | ||
|
a9d407d239 | ||
|
3ca4a33a65 | ||
|
95197f427c | ||
|
84cdfb032c | ||
|
ec2ceb9c96 | ||
|
6286c893fd | ||
|
354aef0e8c | ||
|
139e33c36d | ||
|
e01de59cdd | ||
|
686f822dea | ||
|
9961d5c9af | ||
|
628be0d125 | ||
|
633e45f61a | ||
|
2f357c3805 | ||
|
cda0894d0d | ||
|
117720a8bc | ||
|
a6f6c3613a | ||
|
7914f5b931 | ||
|
a1add0a6f6 | ||
|
c032b337c4 | ||
|
ec363261ae | ||
|
97cde2183d | ||
|
7f43c682db | ||
|
0c9eee3c6b | ||
|
3b1afa3ba6 | ||
|
93e6a75125 | ||
|
52f8a7c0ca | ||
|
55bfeb646f | ||
|
75c9dd3be1 | ||
|
6392e2788f | ||
|
6a97f3f9ba | ||
|
6e5f52e279 | ||
|
7f92bed902 | ||
|
d68a11cc42 | ||
|
328a81e194 | ||
|
31d0908b74 | ||
|
32c77599f4 | ||
|
812ebf3562 | ||
|
37f476013d | ||
|
9f3104166f | ||
|
64cc0daf34 | ||
|
d5d64df124 | ||
|
0edcfcd5c1 | ||
|
50ba2d419a | ||
|
ff3a77ca5a | ||
|
4eaed6c23d | ||
|
4d0dd46471 | ||
|
9c2549bd00 | ||
|
b7c8e0c17f | ||
|
dd3cfe1837 | ||
|
43f525298e | ||
|
1bb1898ab9 | ||
|
9578f24be9 | ||
|
46fae3aed2 | ||
|
e35f91a70a | ||
|
851052fcca | ||
|
5ef81b2952 | ||
|
ef2851c053 | ||
|
0b4387cff5 | ||
|
a40cf11fbf | ||
|
5c495cd223 | ||
|
cf1296dff8 | ||
|
d6d88db6e8 | ||
|
85c2a35257 | ||
|
836d8b1c64 | ||
|
98d8c8ab71 | ||
|
db45013339 | ||
|
a55c37e7f6 | ||
|
46a270fcca | ||
|
967856518e | ||
|
7f93e739fe | ||
|
2cd1422514 | ||
|
feb370b201 | ||
|
d1b34e64d8 | ||
|
b9a1eead40 | ||
|
1e4bfac98c | ||
|
3bb504fbf3 | ||
|
5029791c90 | ||
|
a1a68f0970 | ||
|
f8543d79eb | ||
|
f353415136 | ||
|
26240403b0 | ||
|
3a39729b58 | ||
|
096c961d9a | ||
|
01fe04a6a2 | ||
|
7ea4014993 | ||
|
d50b374f88 | ||
|
27dfb25570 | ||
|
b5ed77985e | ||
|
61243bd15f | ||
|
368b94d804 | ||
|
a5adbbfd5f | ||
|
a19d13f123 | ||
|
78886ab383 | ||
|
168012b465 | ||
|
d9d58ea66e | ||
|
56f5f6e8d5 | ||
|
3cb6420eda | ||
|
60be2c1186 | ||
|
ed210f6b2c | ||
|
029bc59d74 | ||
|
961c08a82f | ||
|
7ee484c614 | ||
|
05c6fbbf99 | ||
|
91078b7f7a | ||
|
20d804afc4 | ||
|
c21f6d1cbf | ||
|
393e79c1fd | ||
|
8b92c8a085 | ||
|
ff73dd94c9 | ||
|
af43904f38 | ||
|
485074f265 | ||
|
2e0ee55b5e | ||
|
e9105d32cb | ||
|
964d23f68c | ||
|
be5aaaae7b | ||
|
bf13bd7b3f | ||
|
352e392fcb | ||
|
083b1b02df | ||
|
648c6240a2 | ||
|
60cab840cb | ||
|
83a4380dab | ||
|
de84fe8d98 | ||
|
ed3cbfdb8e | ||
|
fda44ca17d | ||
|
272025bb07 | ||
|
8e92bcf1b2 | ||
|
84f1ffdefe | ||
|
7e25450054 | ||
|
4a563fa266 | ||
|
aa4c0ec000 | ||
|
e1ecfbdc43 | ||
|
a4e122a82e | ||
|
93216e8fb7 | ||
|
16272c210d | ||
|
e104b00da1 | ||
|
ce5c6bcc08 | ||
|
8694ce31fe | ||
|
d960e5eadd | ||
|
2dc71e87a3 | ||
|
6bf17edde2 | ||
|
88573d515d | ||
|
89b9f77823 | ||
|
765d9be17d | ||
|
7135373008 | ||
|
ee269884fc | ||
|
387540d5f1 | ||
|
2eba7b42a8 | ||
|
07115d26c7 | ||
|
c43ed815a0 | ||
|
ff01e36d12 | ||
|
ac4798b16c | ||
|
d4e14fed0e | ||
|
5f91259344 | ||
|
20a9d9645d | ||
|
c86f6b4abd | ||
|
d66489b5b2 | ||
|
b743ee9f0c | ||
|
95ba69c00a | ||
|
2ac273739c | ||
|
5b4d28708c | ||
|
4cc4383488 | ||
|
8935232248 | ||
|
5c6dd2f172 | ||
|
eeeb7ef5b9 | ||
|
2efc9c1178 | ||
|
a84c46f6e3 | ||
|
a5c3dcdd02 | ||
|
46f7a75eb7 | ||
|
94b6710c5b | ||
|
d8dd3da9ab | ||
|
803ced004a | ||
|
0ea7d36ad0 | ||
|
87aafab759 | ||
|
994d310abd | ||
|
228cdcf05e | ||
|
42598e352c | ||
|
36a9e4d1da | ||
|
456dfd0dea | ||
|
155457e2b5 | ||
|
b5c91485bf | ||
|
c959cf7870 | ||
|
5878c88636 | ||
|
ddcef2fb19 | ||
|
493d124c07 | ||
|
f42060c616 | ||
|
834facc932 | ||
|
f82d0b76ee | ||
|
c25d225275 | ||
|
c503a274b5 | ||
|
087069d215 | ||
|
826a6dd114 | ||
|
f31483838d | ||
|
d8a9b633d9 | ||
|
c060e4466a | ||
|
a9951376f4 | ||
|
bda0c8f5e3 | ||
|
71902f23a2 | ||
|
dfd6c85569 | ||
|
0e41b2cc1a |
762
call_traits.htm
762
call_traits.htm
@@ -1,762 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type"
|
|
||||||
content="text/html; charset=iso-8859-1">
|
|
||||||
<meta name="Template"
|
|
||||||
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
|
|
||||||
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
|
|
||||||
<title>Call Traits</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
|
|
||||||
vlink="#800080">
|
|
||||||
|
|
||||||
<h1><img src="../../c++boost.gif" width="276" height="86">Header
|
|
||||||
<<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>></h1>
|
|
||||||
|
|
||||||
<p>All of the contents of <boost/call_traits.hpp> are
|
|
||||||
defined inside namespace boost.</p>
|
|
||||||
|
|
||||||
<p>The template class call_traits<T> encapsulates the
|
|
||||||
"best" method to pass a parameter of some type T to or
|
|
||||||
from a function, and consists of a collection of typedefs defined
|
|
||||||
as in the table below. The purpose of call_traits is to ensure
|
|
||||||
that problems like "<a href="#refs">references to references</a>"
|
|
||||||
never occur, and that parameters are passed in the most efficient
|
|
||||||
manner possible (see <a href="#examples">examples</a>). In each
|
|
||||||
case if your existing practice is to use the type defined on the
|
|
||||||
left, then replace it with the call_traits defined type on the
|
|
||||||
right. </p>
|
|
||||||
|
|
||||||
<p>Note that for compilers that do not support either partial
|
|
||||||
specialization or member templates, no benefit will occur from
|
|
||||||
using call_traits: the call_traits defined types will always be
|
|
||||||
the same as the existing practice in this case. In addition if
|
|
||||||
only member templates and not partial template specialisation is
|
|
||||||
support by the compiler (for example Visual C++ 6) then
|
|
||||||
call_traits can not be used with array types (although it can be
|
|
||||||
used to solve the reference to reference problem).</p>
|
|
||||||
|
|
||||||
<table border="0" cellpadding="7" cellspacing="1" width="797">
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#008080"><p
|
|
||||||
align="center">Existing practice</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="35%" bgcolor="#008080"><p
|
|
||||||
align="center">call_traits equivalent</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="32%" bgcolor="#008080"><p
|
|
||||||
align="center">Description</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="16%" bgcolor="#008080"><p
|
|
||||||
align="center">Notes</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"><p align="center">T<br>
|
|
||||||
(return by value)</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::value_type</code></p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="32%">Defines a type that
|
|
||||||
represents the "value" of type T. Use this for
|
|
||||||
functions that return by value, or possibly for stored
|
|
||||||
values of type T.</td>
|
|
||||||
<td valign="top" width="16%"><p align="center">2</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"><p align="center">T&<br>
|
|
||||||
(return value)</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::reference</code></p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="32%">Defines a type that
|
|
||||||
represents a reference to type T. Use for functions that
|
|
||||||
would normally return a T&.</td>
|
|
||||||
<td valign="top" width="16%"><p align="center">1</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
T&<br>
|
|
||||||
(return value)</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::const_reference</code></p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="32%">Defines a type that
|
|
||||||
represents a constant reference to type T. Use for
|
|
||||||
functions that would normally return a const T&.</td>
|
|
||||||
<td valign="top" width="16%"><p align="center">1</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
T&<br>
|
|
||||||
(function parameter)</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="32%">Defines a type that
|
|
||||||
represents the "best" way to pass a parameter
|
|
||||||
of type T to a function.</td>
|
|
||||||
<td valign="top" width="16%"><p align="center">1,3</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>Notes:</p>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>If T is already reference type, then call_traits is
|
|
||||||
defined such that <a href="#refs">references to
|
|
||||||
references</a> do not occur (requires partial
|
|
||||||
specialization).</li>
|
|
||||||
<li>If T is an array type, then call_traits defines <code>value_type</code>
|
|
||||||
as a "constant pointer to type" rather than an
|
|
||||||
"array of type" (requires partial
|
|
||||||
specialization). Note that if you are using value_type as
|
|
||||||
a stored value then this will result in storing a "constant
|
|
||||||
pointer to an array" rather than the array itself.
|
|
||||||
This may or may not be a good thing depending upon what
|
|
||||||
you actually need (in other words take care!).</li>
|
|
||||||
<li>If T is a small built in type or a pointer, then <code>param_type</code>
|
|
||||||
is defined as <code>T const</code>, instead of <code>T
|
|
||||||
const&</code>. This can improve the ability of the
|
|
||||||
compiler to optimize loops in the body of the function if
|
|
||||||
they depend upon the passed parameter, the semantics of
|
|
||||||
the passed parameter is otherwise unchanged (requires
|
|
||||||
partial specialization).</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<h3>Copy constructibility</h3>
|
|
||||||
|
|
||||||
<p>The following table defines which call_traits types can always
|
|
||||||
be copy-constructed from which other types, those entries marked
|
|
||||||
with a '?' are true only if and only if T is copy constructible:</p>
|
|
||||||
|
|
||||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"> </td>
|
|
||||||
<td valign="top" colspan="5" width="85%"
|
|
||||||
bgcolor="#008080"><p align="center">To:</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#008080">From:</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">T</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">value_type</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">reference</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">const_reference</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">param_type</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">N</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">N</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">N</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">N</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">?</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">N</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">N</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<p>If T is an assignable type the following assignments are
|
|
||||||
possible:</p>
|
|
||||||
|
|
||||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"> </td>
|
|
||||||
<td valign="top" colspan="5" width="85%"
|
|
||||||
bgcolor="#008080"><p align="center">To:</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#008080">From:</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">T</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">value_type</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">reference</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">const_reference</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">param_type</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">Y</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">-</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<h3><a name="examples"></a>Examples</h3>
|
|
||||||
|
|
||||||
<p>The following table shows the effect that call_traits has on
|
|
||||||
various types, the table assumes that the compiler supports
|
|
||||||
partial specialization: if it doesn't then all types behave in
|
|
||||||
the same way as the entry for "myclass", and
|
|
||||||
call_traits can not be used with reference or array types.</p>
|
|
||||||
|
|
||||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%"> </td>
|
|
||||||
<td valign="top" colspan="5" width="85%"
|
|
||||||
bgcolor="#008080"><p align="center">Call_traits type:</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#008080"><p
|
|
||||||
align="center">Original type T</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">value_type</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">reference</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">const_reference</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">param_type</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">Applies to:</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">myclass</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">myclass</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">myclass&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
myclass&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">myclass
|
|
||||||
const&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All user
|
|
||||||
defined types.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">int</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int const</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All small
|
|
||||||
built-in types.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">int*</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int*</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int*&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int*const&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int* const</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All
|
|
||||||
pointer types.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All
|
|
||||||
reference types.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">const int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const
|
|
||||||
int&</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All
|
|
||||||
constant-references.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">int[3]</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int*</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">int(&)[3]</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int(&)[3]</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int*
|
|
||||||
const</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All array
|
|
||||||
types.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
|
||||||
align="center">const int[3]</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int*</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int(&)[3]</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int(&)[3]</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">const int*
|
|
||||||
const</p>
|
|
||||||
</td>
|
|
||||||
<td valign="top" width="17%"><p align="center">All
|
|
||||||
constant-array types.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<h4>Example 1:</h4>
|
|
||||||
|
|
||||||
<p>The following class is a trivial class that stores some type T
|
|
||||||
by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
|
|
||||||
file), the aim is to illustrate how each of the available
|
|
||||||
call_traits typedefs may be used:</p>
|
|
||||||
|
|
||||||
<pre>template <class T>
|
|
||||||
struct contained
|
|
||||||
{
|
|
||||||
// define our typedefs first, arrays are stored by value
|
|
||||||
// so value_type is not the same as result_type:
|
|
||||||
typedef typename boost::call_traits<T>::param_type param_type;
|
|
||||||
typedef typename boost::call_traits<T>::reference reference;
|
|
||||||
typedef typename boost::call_traits<T>::const_reference const_reference;
|
|
||||||
typedef T value_type;
|
|
||||||
typedef typename boost::call_traits<T>::value_type result_type;
|
|
||||||
|
|
||||||
// stored value:
|
|
||||||
value_type v_;
|
|
||||||
|
|
||||||
// constructors:
|
|
||||||
contained() {}
|
|
||||||
contained(param_type p) : v_(p){}
|
|
||||||
// return byval:
|
|
||||||
result_type value() { return v_; }
|
|
||||||
// return by_ref:
|
|
||||||
reference get() { return v_; }
|
|
||||||
const_reference const_get()const { return v_; }
|
|
||||||
// pass value:
|
|
||||||
void call(param_type p){}
|
|
||||||
|
|
||||||
};</pre>
|
|
||||||
|
|
||||||
<h4><a name="refs"></a>Example 2 (the reference to reference
|
|
||||||
problem):</h4>
|
|
||||||
|
|
||||||
<p>Consider the definition of std::binder1st:</p>
|
|
||||||
|
|
||||||
<pre>template <class Operation>
|
|
||||||
class binder1st :
|
|
||||||
public unary_function<typename Operation::second_argument_type, typename Operation::result_type>
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Operation op;
|
|
||||||
typename Operation::first_argument_type value;
|
|
||||||
public:
|
|
||||||
binder1st(const Operation& x, const typename Operation::first_argument_type& y);
|
|
||||||
typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;
|
|
||||||
}; </pre>
|
|
||||||
|
|
||||||
<p>Now consider what happens in the relatively common case that
|
|
||||||
the functor takes its second argument as a reference, that
|
|
||||||
implies that <code>Operation::second_argument_type</code> is a
|
|
||||||
reference type, <code>operator()</code> will now end up taking a
|
|
||||||
reference to a reference as an argument, and that is not
|
|
||||||
currently legal. The solution here is to modify <code>operator()</code>
|
|
||||||
to use call_traits:</p>
|
|
||||||
|
|
||||||
<pre>typename Operation::result_type operator()(typename call_traits<typename Operation::second_argument_type>::param_type x) const;</pre>
|
|
||||||
|
|
||||||
<p>Now in the case that <code>Operation::second_argument_type</code>
|
|
||||||
is a reference type, the argument is passed as a reference, and
|
|
||||||
the no "reference to reference" occurs.</p>
|
|
||||||
|
|
||||||
<h4><a name="ex3"></a>Example 3 (the make_pair problem):</h4>
|
|
||||||
|
|
||||||
<p>If we pass the name of an array as one (or both) arguments to <code>std::make_pair</code>,
|
|
||||||
then template argument deduction deduces the passed parameter as
|
|
||||||
"const reference to array of T", this also applies to
|
|
||||||
string literals (which are really array literals). Consequently
|
|
||||||
instead of returning a pair of pointers, it tries to return a
|
|
||||||
pair of arrays, and since an array type is not copy-constructible
|
|
||||||
the code fails to compile. One solution is to explicitly cast the
|
|
||||||
arguments to make_pair to pointers, but call_traits provides a
|
|
||||||
better (i.e. automatic) solution (and one that works safely even
|
|
||||||
in generic code where the cast might do the wrong thing):</p>
|
|
||||||
|
|
||||||
<pre>template <class T1, class T2>
|
|
||||||
std::pair<
|
|
||||||
typename boost::call_traits<T1>::value_type,
|
|
||||||
typename boost::call_traits<T2>::value_type>
|
|
||||||
make_pair(const T1& t1, const T2& t2)
|
|
||||||
{
|
|
||||||
return std::pair<
|
|
||||||
typename boost::call_traits<T1>::value_type,
|
|
||||||
typename boost::call_traits<T2>::value_type>(t1, t2);
|
|
||||||
}</pre>
|
|
||||||
|
|
||||||
<p>Here, the deduced argument types will be automatically
|
|
||||||
degraded to pointers if the deduced types are arrays, similar
|
|
||||||
situations occur in the standard binders and adapters: in
|
|
||||||
principle in any function that "wraps" a temporary
|
|
||||||
whose type is deduced. Note that the function arguments to
|
|
||||||
make_pair are not expressed in terms of call_traits: doing so
|
|
||||||
would prevent template argument deduction from functioning.</p>
|
|
||||||
|
|
||||||
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
|
|
||||||
|
|
||||||
<p>The call_traits template will "optimize" the passing
|
|
||||||
of a small built-in type as a function parameter, this mainly has
|
|
||||||
an effect when the parameter is used within a loop body. In the
|
|
||||||
following example (see <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>),
|
|
||||||
a version of std::fill is optimized in two ways: if the type
|
|
||||||
passed is a single byte built-in type then std::memset is used to
|
|
||||||
effect the fill, otherwise a conventional C++ implemention is
|
|
||||||
used, but with the passed parameter "optimized" using
|
|
||||||
call_traits:</p>
|
|
||||||
|
|
||||||
<pre>namespace detail{
|
|
||||||
|
|
||||||
template <bool opt>
|
|
||||||
struct filler
|
|
||||||
{
|
|
||||||
template <typename I, typename T>
|
|
||||||
static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val);
|
|
||||||
{
|
|
||||||
while(first != last)
|
|
||||||
{
|
|
||||||
*first = val;
|
|
||||||
++first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct filler<true>
|
|
||||||
{
|
|
||||||
template <typename I, typename T>
|
|
||||||
static void do_fill(I first, I last, T val)
|
|
||||||
{
|
|
||||||
memset(first, val, last-first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class I, class T>
|
|
||||||
inline void fill(I first, I last, const T& val)
|
|
||||||
{
|
|
||||||
enum{ can_opt = boost::is_pointer<I>::value
|
|
||||||
&& boost::is_arithmetic<T>::value
|
|
||||||
&& (sizeof(T) == 1) };
|
|
||||||
typedef detail::filler<can_opt> filler_t;
|
|
||||||
filler_t::template do_fill<I,T>(first, last, val);
|
|
||||||
}</pre>
|
|
||||||
|
|
||||||
<p>Footnote: the reason that this is "optimal" for
|
|
||||||
small built-in types is that with the value passed as "T
|
|
||||||
const" instead of "const T&" the compiler is
|
|
||||||
able to tell both that the value is constant and that it is free
|
|
||||||
of aliases. With this information the compiler is able to cache
|
|
||||||
the passed value in a register, unroll the loop, or use
|
|
||||||
explicitly parallel instructions: if any of these are supported.
|
|
||||||
Exactly how much mileage you will get from this depends upon your
|
|
||||||
compiler - we could really use some accurate benchmarking
|
|
||||||
software as part of boost for cases like this.</p>
|
|
||||||
|
|
||||||
<p>Note that the function arguments to fill are not expressed in
|
|
||||||
terms of call_traits: doing so would prevent template argument
|
|
||||||
deduction from functioning. Instead fill acts as a "thin
|
|
||||||
wrapper" that is there to perform template argument
|
|
||||||
deduction, the compiler will optimise away the call to fill all
|
|
||||||
together, replacing it with the call to filler<>::do_fill,
|
|
||||||
which does use call_traits.</p>
|
|
||||||
|
|
||||||
<h3>Rationale</h3>
|
|
||||||
|
|
||||||
<p>The following notes are intended to briefly describe the
|
|
||||||
rational behind choices made in call_traits.</p>
|
|
||||||
|
|
||||||
<p>All user-defined types follow "existing practice"
|
|
||||||
and need no comment.</p>
|
|
||||||
|
|
||||||
<p>Small built-in types (what the standard calls fundamental
|
|
||||||
types [3.9.1]) differ from existing practice only in the <i>param_type</i>
|
|
||||||
typedef. In this case passing "T const" is compatible
|
|
||||||
with existing practice, but may improve performance in some cases
|
|
||||||
(see <a href="#ex4">Example 4</a>), in any case this should never
|
|
||||||
be any worse than existing practice.</p>
|
|
||||||
|
|
||||||
<p>Pointers follow the same rational as small built-in types.</p>
|
|
||||||
|
|
||||||
<p>For reference types the rational follows <a href="#refs">Example
|
|
||||||
2</a> - references to references are not allowed, so the
|
|
||||||
call_traits members must be defined such that these problems do
|
|
||||||
not occur. There is a proposal to modify the language such that
|
|
||||||
"a reference to a reference is a reference" (issue #106,
|
|
||||||
submitted by Bjarne Stroustrup), call_traits<T>::value_type
|
|
||||||
and call_traits<T>::param_type both provide the same effect
|
|
||||||
as that proposal, without the need for a language change (in
|
|
||||||
other words it's a workaround).</p>
|
|
||||||
|
|
||||||
<p>For array types, a function that takes an array as an argument
|
|
||||||
will degrade the array type to a pointer type: this means that
|
|
||||||
the type of the actual parameter is different from its declared
|
|
||||||
type, something that can cause endless problems in template code
|
|
||||||
that relies on the declared type of a parameter. For example:</p>
|
|
||||||
|
|
||||||
<pre>template <class T>
|
|
||||||
struct A
|
|
||||||
{
|
|
||||||
void foo(T t);
|
|
||||||
};</pre>
|
|
||||||
|
|
||||||
<p><font face="Times New Roman">In this case if we instantiate
|
|
||||||
A<int[2]> then the declared type of the parameter passed to
|
|
||||||
member function foo is int[2], but it's actual type is const int*,
|
|
||||||
if we try to use the type T within the function body, then there
|
|
||||||
is a strong likelyhood that our code will not compile:</font></p>
|
|
||||||
|
|
||||||
<pre>template <class T>
|
|
||||||
void A<T>::foo(T t)
|
|
||||||
{
|
|
||||||
T dup(t); // doesn't compile for case that T is an array.
|
|
||||||
}</pre>
|
|
||||||
|
|
||||||
<p>By using call_traits the degradation from array to pointer is
|
|
||||||
explicit, and the type of the parameter is the same as it's
|
|
||||||
declared type:</p>
|
|
||||||
|
|
||||||
<pre>template <class T>
|
|
||||||
struct A
|
|
||||||
{
|
|
||||||
void foo(typename call_traits<T>::value_type t);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void A<T>::foo(typename call_traits<T>::value_type t)
|
|
||||||
{
|
|
||||||
typename call_traits<T>::value_type dup(t); // OK even if T is an array type.
|
|
||||||
}</pre>
|
|
||||||
|
|
||||||
<p>For value_type (return by value), again only a pointer may be
|
|
||||||
returned, not a copy of the whole array, and again call_traits
|
|
||||||
makes the degradation explicit. The value_type member is useful
|
|
||||||
whenever an array must be explicitly degraded to a pointer - <a
|
|
||||||
href="#ex3">Example 3</a> provides the test case (Footnote: the
|
|
||||||
array specialisation for call_traits is the least well understood
|
|
||||||
of all the call_traits specialisations, if the given semantics
|
|
||||||
cause specific problems for you, or don't solve a particular
|
|
||||||
array-related problem, then I would be interested to hear about
|
|
||||||
it. Most people though will probably never need to use this
|
|
||||||
specialisation).</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>Revised 01 September 2000</p>
|
|
||||||
|
|
||||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
|
|
||||||
sell and distribute this document is granted provided this
|
|
||||||
copyright notice appears in all copies. This document is provided
|
|
||||||
"as is" without express or implied warranty, and with
|
|
||||||
no claim as to its suitability for any purpose.</p>
|
|
||||||
|
|
||||||
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
|
|
||||||
Hinnant and John Maddock.</p>
|
|
||||||
|
|
||||||
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
|
|
||||||
Maddock</a>, the latest version of this file can be found at <a
|
|
||||||
href="http://www.boost.org/">www.boost.org</a>, and the boost
|
|
||||||
discussion list at <a href="http://www.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
|
|
||||||
|
|
||||||
<p>.</p>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,366 +0,0 @@
|
|||||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
|
||||||
// distribute this software is granted provided this copyright notice appears in
|
|
||||||
// all copies. This software is provided "as is" without express or implied
|
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
//
|
|
||||||
// See http://www.boost.org for most recent version including documentation.
|
|
||||||
//
|
|
||||||
// Revision History
|
|
||||||
// 11 Feb 2001 Compile with Borland, re-enable failing tests (David Abrahams)
|
|
||||||
// 29 Jan 2001 Initial revision (David Abrahams)
|
|
||||||
|
|
||||||
#include <boost/half_open_range.hpp>
|
|
||||||
#include <boost/utility.hpp>
|
|
||||||
#include <iterator>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <cassert>
|
|
||||||
#include <stdexcept>
|
|
||||||
#ifndef BOOST_NO_LIMITS
|
|
||||||
# include <limits>
|
|
||||||
#endif
|
|
||||||
#ifndef BOOST_NO_SLIST
|
|
||||||
# include <slist>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline unsigned unsigned_random(unsigned max)
|
|
||||||
{
|
|
||||||
return (max > 0) ? (unsigned)rand() % max : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special tests for ranges supporting random access
|
|
||||||
template <class T>
|
|
||||||
void category_test_1(
|
|
||||||
const boost::half_open_range<T>& r, std::random_access_iterator_tag)
|
|
||||||
{
|
|
||||||
typedef boost::half_open_range<T> range;
|
|
||||||
typedef typename range::size_type size_type;
|
|
||||||
size_type size = r.size();
|
|
||||||
|
|
||||||
// pick a random offset
|
|
||||||
size_type offset = unsigned_random(size);
|
|
||||||
|
|
||||||
typename range::value_type x = *(r.begin() + offset);
|
|
||||||
// test contains(value_type)
|
|
||||||
assert(r.contains(r.start()) == !r.empty());
|
|
||||||
assert(!r.contains(r.finish()));
|
|
||||||
assert(r.contains(x) == (offset != size));
|
|
||||||
|
|
||||||
range::const_iterator p = r.find(x);
|
|
||||||
assert((p == r.end()) == (x == r.finish()));
|
|
||||||
assert(r.find(r.finish()) == r.end());
|
|
||||||
|
|
||||||
if (offset != size)
|
|
||||||
{
|
|
||||||
assert(x == r[offset]);
|
|
||||||
assert(x == r.at(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool caught_out_of_range = false;
|
|
||||||
try {
|
|
||||||
bool never_initialized = x == r.at(size);
|
|
||||||
(void)never_initialized;
|
|
||||||
}
|
|
||||||
catch(std::out_of_range&)
|
|
||||||
{
|
|
||||||
caught_out_of_range = true;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
assert(caught_out_of_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Those tests must be skipped for other ranges
|
|
||||||
template <class T>
|
|
||||||
void category_test_1(
|
|
||||||
const boost::half_open_range<T>&, std::forward_iterator_tag)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned indices[][2] = { {0,0},{0,1},{0,2},{0,3},
|
|
||||||
{1,1},{1,2},{1,3},
|
|
||||||
{2,2},{2,3},
|
|
||||||
{3,3}};
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
void category_test_2(
|
|
||||||
const std::vector<Range>& ranges, unsigned i, unsigned j, std::random_access_iterator_tag)
|
|
||||||
{
|
|
||||||
typedef Range range;
|
|
||||||
const range& ri = ranges[i];
|
|
||||||
const range& rj = ranges[j];
|
|
||||||
|
|
||||||
if (indices[i][0] <= indices[j][0] && indices[i][1] >= indices[j][1])
|
|
||||||
assert(ri.contains(rj));
|
|
||||||
|
|
||||||
if (ri.contains(rj))
|
|
||||||
assert((ri & rj) == rj);
|
|
||||||
assert(boost::intersects(ri, rj) == !(ri & rj).empty());
|
|
||||||
|
|
||||||
range t1(ri);
|
|
||||||
t1 &= rj;
|
|
||||||
assert(t1 == range(indices[i][0] > indices[j][0] ? ri.start() : rj.start(),
|
|
||||||
indices[i][1] < indices[j][1] ? ri.finish() : rj.finish()));
|
|
||||||
assert(t1 == (ri & rj));
|
|
||||||
|
|
||||||
range t2(ri);
|
|
||||||
t2 |= rj;
|
|
||||||
|
|
||||||
if (ri.empty())
|
|
||||||
assert(t2 == rj);
|
|
||||||
else if (rj.empty())
|
|
||||||
assert(t2 == ri);
|
|
||||||
else
|
|
||||||
assert(t2 == range(indices[i][0] < indices[j][0] ? ri.start() : rj.start(),
|
|
||||||
indices[i][1] > indices[j][1] ? ri.finish() : rj.finish()));
|
|
||||||
assert(t2 == (ri | rj));
|
|
||||||
if (i == j)
|
|
||||||
assert(ri == rj);
|
|
||||||
|
|
||||||
if (ri.empty() || rj.empty())
|
|
||||||
assert((ri == rj) == (ri.empty() && rj.empty()));
|
|
||||||
else
|
|
||||||
assert((ri == rj) == (ri.start() == rj.start() && ri.finish() == rj.finish()));
|
|
||||||
|
|
||||||
assert((ri == rj) == !(ri != rj));
|
|
||||||
|
|
||||||
bool same = ri == rj;
|
|
||||||
bool one_empty = ri.empty() != rj.empty();
|
|
||||||
|
|
||||||
std::less<range> less;
|
|
||||||
std::less_equal<range> less_equal;
|
|
||||||
std::greater<range> greater;
|
|
||||||
std::greater_equal<range> greater_equal;
|
|
||||||
|
|
||||||
if (same)
|
|
||||||
{
|
|
||||||
assert(greater_equal(ri,rj));
|
|
||||||
assert(less_equal(ri,rj));
|
|
||||||
assert(!greater(ri,rj));
|
|
||||||
assert(!less(ri,rj));
|
|
||||||
}
|
|
||||||
else if (one_empty)
|
|
||||||
{
|
|
||||||
const range& empty = ri.empty() ? ri : rj;
|
|
||||||
const range& non_empty = rj.empty() ? ri : rj;
|
|
||||||
|
|
||||||
assert(less(empty,non_empty));
|
|
||||||
assert(less_equal(empty,non_empty));
|
|
||||||
assert(!greater(empty,non_empty));
|
|
||||||
assert(!greater_equal(empty,non_empty));
|
|
||||||
assert(!less(non_empty,empty));
|
|
||||||
assert(!less_equal(non_empty,empty));
|
|
||||||
assert(greater(non_empty,empty));
|
|
||||||
assert(greater_equal(non_empty,empty));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (indices[i][0] < indices[j][0] ||
|
|
||||||
indices[i][0] == indices[j][0] && indices[i][1] < indices[j][1])
|
|
||||||
{
|
|
||||||
assert(!greater_equal(ri,rj));
|
|
||||||
assert(less(ri,rj));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indices[i][0] < indices[j][0] ||
|
|
||||||
indices[i][0] == indices[j][0] && indices[i][1] <= indices[j][1])
|
|
||||||
{
|
|
||||||
assert(!greater(ri,rj));
|
|
||||||
assert(less_equal(ri,rj));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indices[i][0] > indices[j][0] ||
|
|
||||||
indices[i][0] == indices[j][0] && indices[i][1] > indices[j][1])
|
|
||||||
{
|
|
||||||
assert(!less_equal(ri,rj));
|
|
||||||
assert(greater(ri,rj));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indices[i][0] > indices[j][0] ||
|
|
||||||
indices[i][0] == indices[j][0] && indices[i][1] >= indices[j][1])
|
|
||||||
{
|
|
||||||
assert(!less(ri,rj));
|
|
||||||
assert(greater_equal(ri,rj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
void category_test_2(
|
|
||||||
const std::vector<Range>&, unsigned, unsigned, std::forward_iterator_tag)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void category_test_2(
|
|
||||||
const std::vector<boost::half_open_range<T> >&, unsigned, unsigned, std::bidirectional_iterator_tag)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
void test_back(Range& x, std::bidirectional_iterator_tag)
|
|
||||||
{
|
|
||||||
assert(x.back() == boost::prior(x.finish()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
void test_back(Range& x, std::forward_iterator_tag)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
boost::half_open_range<T> range_identity(const boost::half_open_range<T>& x)
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void test(T x0, T x1, T x2, T x3)
|
|
||||||
{
|
|
||||||
std::vector<boost::half_open_range<T> > ranges;
|
|
||||||
typedef boost::half_open_range<T> range;
|
|
||||||
|
|
||||||
T bounds[4] = { x0, x1, x2, x3 };
|
|
||||||
|
|
||||||
const std::size_t num_ranges = sizeof(indices)/sizeof(*indices);
|
|
||||||
// test construction
|
|
||||||
for (std::size_t n = 0; n < num_ranges;++n)
|
|
||||||
{
|
|
||||||
T start = bounds[indices[n][0]];
|
|
||||||
T finish = bounds[indices[n][1]];
|
|
||||||
boost::half_open_range<T> r(start, finish);
|
|
||||||
ranges.push_back(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test implicit conversion from std::pair<T,T>
|
|
||||||
range converted = std::pair<T,T>(x0,x0);
|
|
||||||
(void)converted;
|
|
||||||
|
|
||||||
// test assignment, equality and inequality
|
|
||||||
range r00 = range(x0, x0);
|
|
||||||
assert(r00 == range(x0,x0));
|
|
||||||
assert(r00 == range(x1,x1)); // empty ranges are all equal
|
|
||||||
if (x3 != x0)
|
|
||||||
assert(r00 != range(x0, x3));
|
|
||||||
r00 = range(x0, x3);
|
|
||||||
assert(r00 == range(x0, x3));
|
|
||||||
if (x3 != x0)
|
|
||||||
assert(r00 != range(x0, x0));
|
|
||||||
|
|
||||||
typedef typename range::iterator iterator;
|
|
||||||
typedef typename iterator::iterator_category category;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_ranges; ++i)
|
|
||||||
{
|
|
||||||
const range& r = ranges[i];
|
|
||||||
|
|
||||||
// test begin(), end(), basic iteration.
|
|
||||||
unsigned count = 0;
|
|
||||||
for (range::const_iterator p = r.begin(), finish = r.end();
|
|
||||||
p != finish;
|
|
||||||
++p, ++count)
|
|
||||||
{
|
|
||||||
assert(count < 2100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test size(), empty(), front(), back()
|
|
||||||
assert((unsigned)r.size() == count);
|
|
||||||
if (indices[i][0] == indices[i][1])
|
|
||||||
assert(r.empty());
|
|
||||||
if (r.empty())
|
|
||||||
assert(r.size() == 0);
|
|
||||||
if (!r.empty())
|
|
||||||
{
|
|
||||||
assert(r.front() == r.start());
|
|
||||||
test_back(r, category());
|
|
||||||
}
|
|
||||||
|
|
||||||
// test swap
|
|
||||||
range r1(r);
|
|
||||||
range r2(x0,x3);
|
|
||||||
const bool same = r1 == r2;
|
|
||||||
r1.swap(r2);
|
|
||||||
assert(r1 == range(x0,x3));
|
|
||||||
assert(r2 == r);
|
|
||||||
if (!same) {
|
|
||||||
assert(r1 != r);
|
|
||||||
assert(r2 != range(x0,x3));
|
|
||||||
}
|
|
||||||
|
|
||||||
// do individual tests for random-access iterators
|
|
||||||
category_test_1(r, category());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < num_ranges; ++j) {
|
|
||||||
for (unsigned k = 0; k < num_ranges; ++k) {
|
|
||||||
category_test_2(ranges, j, k, category());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Integer>
|
|
||||||
void test_integer(Integer* = 0) // default arg works around MSVC bug
|
|
||||||
{
|
|
||||||
Integer a = 0;
|
|
||||||
Integer b = a + unsigned_random(128 - a);
|
|
||||||
Integer c = b + unsigned_random(128 - b);
|
|
||||||
Integer d = c + unsigned_random(128 - c);
|
|
||||||
|
|
||||||
test(a, b, c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Container>
|
|
||||||
void test_container(Container* = 0) // default arg works around MSVC bug
|
|
||||||
{
|
|
||||||
Container c(unsigned_random(1673));
|
|
||||||
|
|
||||||
const typename Container::size_type offset1 = unsigned_random(c.size());
|
|
||||||
const typename Container::size_type offset2 = unsigned_random(c.size() - offset1);
|
|
||||||
typename Container::iterator internal1 = c.begin();
|
|
||||||
std::advance(internal1, offset1);
|
|
||||||
typename Container::iterator internal2 = internal1;
|
|
||||||
std::advance(internal2, offset2);
|
|
||||||
|
|
||||||
test(c.begin(), internal1, internal2, c.end());
|
|
||||||
|
|
||||||
typedef typename Container::const_iterator const_iterator;
|
|
||||||
test(const_iterator(c.begin()),
|
|
||||||
const_iterator(internal1),
|
|
||||||
const_iterator(internal2),
|
|
||||||
const_iterator(c.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// Test the built-in integer types.
|
|
||||||
test_integer<char>();
|
|
||||||
test_integer<unsigned char>();
|
|
||||||
test_integer<signed char>();
|
|
||||||
test_integer<wchar_t>();
|
|
||||||
test_integer<short>();
|
|
||||||
test_integer<unsigned short>();
|
|
||||||
test_integer<int>();
|
|
||||||
test_integer<unsigned int>();
|
|
||||||
test_integer<long>();
|
|
||||||
test_integer<unsigned long>();
|
|
||||||
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
|
|
||||||
test_integer<long long>();
|
|
||||||
test_integer<unsigned long long>();
|
|
||||||
#endif
|
|
||||||
// Some tests on container iterators, to prove we handle a few different categories
|
|
||||||
test_container<std::vector<int> >();
|
|
||||||
test_container<std::list<int> >();
|
|
||||||
#ifndef BOOST_NO_SLIST
|
|
||||||
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
|
|
||||||
#endif
|
|
||||||
// Also prove that we can handle raw pointers.
|
|
||||||
int array[2000];
|
|
||||||
const std::size_t a = 0;
|
|
||||||
const std::size_t b = a + unsigned_random(2000 - a);
|
|
||||||
const std::size_t c = b + unsigned_random(2000 - b);
|
|
||||||
test(array, array+b, array+c, array+2000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
38
include/boost/assert.hpp
Normal file
38
include/boost/assert.hpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// boost/assert.hpp - BOOST_ASSERT(expr)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||||
|
//
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
// Note: There are no include guards. This is intentional.
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility/assert.html for documentation.
|
||||||
|
//
|
||||||
|
|
||||||
|
#undef BOOST_ASSERT
|
||||||
|
|
||||||
|
#if defined(BOOST_DISABLE_ASSERTS)
|
||||||
|
|
||||||
|
# define BOOST_ASSERT(expr) ((void)0)
|
||||||
|
|
||||||
|
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
||||||
|
|
||||||
|
#include <boost/current_function.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||||
|
|
||||||
|
#else
|
||||||
|
# include <assert.h>
|
||||||
|
# define BOOST_ASSERT(expr) assert(expr)
|
||||||
|
#endif
|
24
include/boost/call_traits.hpp
Normal file
24
include/boost/call_traits.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||||
|
// Use, modification and distribution are subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt).
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||||
|
|
||||||
|
// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
|
||||||
|
// for full copyright notices.
|
||||||
|
|
||||||
|
#ifndef BOOST_CALL_TRAITS_HPP
|
||||||
|
#define BOOST_CALL_TRAITS_HPP
|
||||||
|
|
||||||
|
#ifndef BOOST_CONFIG_HPP
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
#include <boost/detail/ob_call_traits.hpp>
|
||||||
|
#else
|
||||||
|
#include <boost/detail/call_traits.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_CALL_TRAITS_HPP
|
71
include/boost/checked_delete.hpp
Normal file
71
include/boost/checked_delete.hpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
|
||||||
|
#define BOOST_CHECKED_DELETE_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost/checked_delete.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 1999, 2000, 2001, 2002 boost.org
|
||||||
|
// Copyright (c) 2002, 2003 Peter Dimov
|
||||||
|
// Copyright (c) 2003 Daniel Frey
|
||||||
|
// Copyright (c) 2003 Howard Hinnant
|
||||||
|
//
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility/checked_delete.html for documentation.
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
// verify that types are complete for increased safety
|
||||||
|
|
||||||
|
template<class T> inline void checked_delete(T * x)
|
||||||
|
{
|
||||||
|
// intentionally complex - simplification causes regressions
|
||||||
|
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
|
||||||
|
(void) sizeof(type_must_be_complete);
|
||||||
|
delete x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline void checked_array_delete(T * x)
|
||||||
|
{
|
||||||
|
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
|
||||||
|
(void) sizeof(type_must_be_complete);
|
||||||
|
delete [] x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> struct checked_deleter
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
typedef T * argument_type;
|
||||||
|
|
||||||
|
void operator()(T * x) const
|
||||||
|
{
|
||||||
|
// boost:: disables ADL
|
||||||
|
boost::checked_delete(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct checked_array_deleter
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
typedef T * argument_type;
|
||||||
|
|
||||||
|
void operator()(T * x) const
|
||||||
|
{
|
||||||
|
boost::checked_array_delete(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
|
24
include/boost/compressed_pair.hpp
Normal file
24
include/boost/compressed_pair.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||||
|
// Use, modification and distribution are subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt).
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||||
|
|
||||||
|
// See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp
|
||||||
|
// for full copyright notices.
|
||||||
|
|
||||||
|
#ifndef BOOST_COMPRESSED_PAIR_HPP
|
||||||
|
#define BOOST_COMPRESSED_PAIR_HPP
|
||||||
|
|
||||||
|
#ifndef BOOST_CONFIG_HPP
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
#include <boost/detail/ob_compressed_pair.hpp>
|
||||||
|
#else
|
||||||
|
#include <boost/detail/compressed_pair.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_COMPRESSED_PAIR_HPP
|
64
include/boost/current_function.hpp
Normal file
64
include/boost/current_function.hpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
|
||||||
|
#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost/current_function.hpp - BOOST_CURRENT_FUNCTION
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||||
|
//
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
// http://www.boost.org/libs/utility/current_function.html
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void current_function_helper()
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600))
|
||||||
|
|
||||||
|
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
|
||||||
|
|
||||||
|
#elif defined(__FUNCSIG__)
|
||||||
|
|
||||||
|
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
|
||||||
|
|
||||||
|
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
|
||||||
|
|
||||||
|
# define BOOST_CURRENT_FUNCTION __FUNCTION__
|
||||||
|
|
||||||
|
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
|
||||||
|
|
||||||
|
# define BOOST_CURRENT_FUNCTION __FUNC__
|
||||||
|
|
||||||
|
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
|
||||||
|
|
||||||
|
# define BOOST_CURRENT_FUNCTION __func__
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# define BOOST_CURRENT_FUNCTION "(unknown)"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
|
154
include/boost/detail/call_traits.hpp
Normal file
154
include/boost/detail/call_traits.hpp
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||||
|
// Use, modification and distribution are subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt).
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||||
|
|
||||||
|
// call_traits: defines typedefs for function usage
|
||||||
|
// (see libs/utility/call_traits.htm)
|
||||||
|
|
||||||
|
/* Release notes:
|
||||||
|
23rd July 2000:
|
||||||
|
Fixed array specialization. (JM)
|
||||||
|
Added Borland specific fixes for reference types
|
||||||
|
(issue raised by Steve Cleary).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
|
||||||
|
#define BOOST_DETAIL_CALL_TRAITS_HPP
|
||||||
|
|
||||||
|
#ifndef BOOST_CONFIG_HPP
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#endif
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_arithmetic.hpp>
|
||||||
|
#include <boost/type_traits/is_pointer.hpp>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
|
||||||
|
namespace detail{
|
||||||
|
|
||||||
|
template <typename T, bool small_>
|
||||||
|
struct ct_imp2
|
||||||
|
{
|
||||||
|
typedef const T& param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ct_imp2<T, true>
|
||||||
|
{
|
||||||
|
typedef const T param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, bool isp, bool b1>
|
||||||
|
struct ct_imp
|
||||||
|
{
|
||||||
|
typedef const T& param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, bool isp>
|
||||||
|
struct ct_imp<T, isp, true>
|
||||||
|
{
|
||||||
|
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, bool b1>
|
||||||
|
struct ct_imp<T, true, b1>
|
||||||
|
{
|
||||||
|
typedef T const param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
//
|
||||||
|
// C++ Builder workaround: we should be able to define a compile time
|
||||||
|
// constant and pass that as a single template parameter to ct_imp<T,bool>,
|
||||||
|
// however compiler bugs prevent this - instead pass three bool's to
|
||||||
|
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation
|
||||||
|
// of ct_imp to handle the logic. (JM)
|
||||||
|
typedef typename detail::ct_imp<
|
||||||
|
T,
|
||||||
|
::boost::is_pointer<T>::value,
|
||||||
|
::boost::is_arithmetic<T>::value
|
||||||
|
>::param_type param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits<T&>
|
||||||
|
{
|
||||||
|
typedef T& value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T& param_type; // hh removed const
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
|
||||||
|
// these are illegal specialisations; cv-qualifies applied to
|
||||||
|
// references have no effect according to [8.3.2p1],
|
||||||
|
// C++ Builder requires them though as it treats cv-qualified
|
||||||
|
// references as distinct types...
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits<T&const>
|
||||||
|
{
|
||||||
|
typedef T& value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T& param_type; // hh removed const
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits<T&volatile>
|
||||||
|
{
|
||||||
|
typedef T& value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T& param_type; // hh removed const
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits<T&const volatile>
|
||||||
|
{
|
||||||
|
typedef T& value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T& param_type; // hh removed const
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
struct call_traits<T [N]>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef T array_type[N];
|
||||||
|
public:
|
||||||
|
// degrades array to pointer:
|
||||||
|
typedef const T* value_type;
|
||||||
|
typedef array_type& reference;
|
||||||
|
typedef const array_type& const_reference;
|
||||||
|
typedef const T* const param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
struct call_traits<const T [N]>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef const T array_type[N];
|
||||||
|
public:
|
||||||
|
// degrades array to pointer:
|
||||||
|
typedef const T* value_type;
|
||||||
|
typedef array_type& reference;
|
||||||
|
typedef const array_type& const_reference;
|
||||||
|
typedef const T* const param_type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_DETAIL_CALL_TRAITS_HPP
|
434
include/boost/detail/compressed_pair.hpp
Normal file
434
include/boost/detail/compressed_pair.hpp
Normal file
@@ -0,0 +1,434 @@
|
|||||||
|
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||||
|
// Use, modification and distribution are subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt).
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||||
|
|
||||||
|
// compressed_pair: pair that "compresses" empty members
|
||||||
|
// (see libs/utility/compressed_pair.htm)
|
||||||
|
//
|
||||||
|
// JM changes 25 Jan 2004:
|
||||||
|
// For the case where T1 == T2 and both are empty, then first() and second()
|
||||||
|
// should return different objects.
|
||||||
|
// JM changes 25 Jan 2000:
|
||||||
|
// Removed default arguments from compressed_pair_switch to get
|
||||||
|
// C++ Builder 4 to accept them
|
||||||
|
// rewriten swap to get gcc and C++ builder to compile.
|
||||||
|
// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
|
||||||
|
|
||||||
|
#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||||
|
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
#include <boost/type_traits/is_empty.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/call_traits.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair;
|
||||||
|
|
||||||
|
|
||||||
|
// compressed_pair
|
||||||
|
|
||||||
|
namespace details
|
||||||
|
{
|
||||||
|
// JM altered 26 Jan 2000:
|
||||||
|
template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
|
||||||
|
struct compressed_pair_switch;
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_switch<T1, T2, false, false, false>
|
||||||
|
{static const int value = 0;};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_switch<T1, T2, false, true, true>
|
||||||
|
{static const int value = 3;};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_switch<T1, T2, false, true, false>
|
||||||
|
{static const int value = 1;};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_switch<T1, T2, false, false, true>
|
||||||
|
{static const int value = 2;};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_switch<T1, T2, true, true, true>
|
||||||
|
{static const int value = 4;};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_switch<T1, T2, true, false, false>
|
||||||
|
{static const int value = 5;};
|
||||||
|
|
||||||
|
template <class T1, class T2, int Version> class compressed_pair_imp;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// workaround for GCC (JM):
|
||||||
|
using std::swap;
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// can't call unqualified swap from within classname::swap
|
||||||
|
// as Koenig lookup rules will find only the classname::swap
|
||||||
|
// member function not the global declaration, so use cp_swap
|
||||||
|
// as a forwarding function (JM):
|
||||||
|
template <typename T>
|
||||||
|
inline void cp_swap(T& t1, T& t2)
|
||||||
|
{
|
||||||
|
#ifndef __GNUC__
|
||||||
|
using std::swap;
|
||||||
|
#endif
|
||||||
|
swap(t1, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 derive from neither
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_imp<T1, T2, 0>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_imp() {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||||
|
: first_(x), second_(y) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x)
|
||||||
|
: first_(x) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(second_param_type y)
|
||||||
|
: second_(y) {}
|
||||||
|
|
||||||
|
first_reference first() {return first_;}
|
||||||
|
first_const_reference first() const {return first_;}
|
||||||
|
|
||||||
|
second_reference second() {return second_;}
|
||||||
|
second_const_reference second() const {return second_;}
|
||||||
|
|
||||||
|
void swap(::boost::compressed_pair<T1, T2>& y)
|
||||||
|
{
|
||||||
|
cp_swap(first_, y.first());
|
||||||
|
cp_swap(second_, y.second());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
first_type first_;
|
||||||
|
second_type second_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 1 derive from T1
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_imp<T1, T2, 1>
|
||||||
|
: private T1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_imp() {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||||
|
: first_type(x), second_(y) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x)
|
||||||
|
: first_type(x) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(second_param_type y)
|
||||||
|
: second_(y) {}
|
||||||
|
|
||||||
|
first_reference first() {return *this;}
|
||||||
|
first_const_reference first() const {return *this;}
|
||||||
|
|
||||||
|
second_reference second() {return second_;}
|
||||||
|
second_const_reference second() const {return second_;}
|
||||||
|
|
||||||
|
void swap(::boost::compressed_pair<T1,T2>& y)
|
||||||
|
{
|
||||||
|
// no need to swap empty base class:
|
||||||
|
cp_swap(second_, y.second());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
second_type second_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2 derive from T2
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_imp<T1, T2, 2>
|
||||||
|
: private T2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_imp() {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||||
|
: second_type(y), first_(x) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x)
|
||||||
|
: first_(x) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(second_param_type y)
|
||||||
|
: second_type(y) {}
|
||||||
|
|
||||||
|
first_reference first() {return first_;}
|
||||||
|
first_const_reference first() const {return first_;}
|
||||||
|
|
||||||
|
second_reference second() {return *this;}
|
||||||
|
second_const_reference second() const {return *this;}
|
||||||
|
|
||||||
|
void swap(::boost::compressed_pair<T1,T2>& y)
|
||||||
|
{
|
||||||
|
// no need to swap empty base class:
|
||||||
|
cp_swap(first_, y.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
first_type first_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3 derive from T1 and T2
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_imp<T1, T2, 3>
|
||||||
|
: private T1,
|
||||||
|
private T2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_imp() {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||||
|
: first_type(x), second_type(y) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x)
|
||||||
|
: first_type(x) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(second_param_type y)
|
||||||
|
: second_type(y) {}
|
||||||
|
|
||||||
|
first_reference first() {return *this;}
|
||||||
|
first_const_reference first() const {return *this;}
|
||||||
|
|
||||||
|
second_reference second() {return *this;}
|
||||||
|
second_const_reference second() const {return *this;}
|
||||||
|
//
|
||||||
|
// no need to swap empty bases:
|
||||||
|
void swap(::boost::compressed_pair<T1,T2>&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// JM
|
||||||
|
// 4 T1 == T2, T1 and T2 both empty
|
||||||
|
// Note does not actually store an instance of T2 at all -
|
||||||
|
// but reuses T1 base class for both first() and second().
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_imp<T1, T2, 4>
|
||||||
|
: private T1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_imp() {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||||
|
: first_type(x), m_second(y) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x)
|
||||||
|
: first_type(x), m_second(x) {}
|
||||||
|
|
||||||
|
first_reference first() {return *this;}
|
||||||
|
first_const_reference first() const {return *this;}
|
||||||
|
|
||||||
|
second_reference second() {return m_second;}
|
||||||
|
second_const_reference second() const {return m_second;}
|
||||||
|
|
||||||
|
void swap(::boost::compressed_pair<T1,T2>&) {}
|
||||||
|
private:
|
||||||
|
T2 m_second;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 5 T1 == T2 and are not empty: //JM
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_imp<T1, T2, 5>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_imp() {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||||
|
: first_(x), second_(y) {}
|
||||||
|
|
||||||
|
compressed_pair_imp(first_param_type x)
|
||||||
|
: first_(x), second_(x) {}
|
||||||
|
|
||||||
|
first_reference first() {return first_;}
|
||||||
|
first_const_reference first() const {return first_;}
|
||||||
|
|
||||||
|
second_reference second() {return second_;}
|
||||||
|
second_const_reference second() const {return second_;}
|
||||||
|
|
||||||
|
void swap(::boost::compressed_pair<T1, T2>& y)
|
||||||
|
{
|
||||||
|
cp_swap(first_, y.first());
|
||||||
|
cp_swap(second_, y.second());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
first_type first_;
|
||||||
|
second_type second_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // details
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair
|
||||||
|
: private ::boost::details::compressed_pair_imp<T1, T2,
|
||||||
|
::boost::details::compressed_pair_switch<
|
||||||
|
T1,
|
||||||
|
T2,
|
||||||
|
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
|
||||||
|
::boost::is_empty<T1>::value,
|
||||||
|
::boost::is_empty<T2>::value>::value>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef details::compressed_pair_imp<T1, T2,
|
||||||
|
::boost::details::compressed_pair_switch<
|
||||||
|
T1,
|
||||||
|
T2,
|
||||||
|
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
|
||||||
|
::boost::is_empty<T1>::value,
|
||||||
|
::boost::is_empty<T2>::value>::value> base;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair() : base() {}
|
||||||
|
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
|
||||||
|
explicit compressed_pair(first_param_type x) : base(x) {}
|
||||||
|
explicit compressed_pair(second_param_type y) : base(y) {}
|
||||||
|
|
||||||
|
first_reference first() {return base::first();}
|
||||||
|
first_const_reference first() const {return base::first();}
|
||||||
|
|
||||||
|
second_reference second() {return base::second();}
|
||||||
|
second_const_reference second() const {return base::second();}
|
||||||
|
|
||||||
|
void swap(compressed_pair& y) { base::swap(y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// JM
|
||||||
|
// Partial specialisation for case where T1 == T2:
|
||||||
|
//
|
||||||
|
template <class T>
|
||||||
|
class compressed_pair<T, T>
|
||||||
|
: private details::compressed_pair_imp<T, T,
|
||||||
|
::boost::details::compressed_pair_switch<
|
||||||
|
T,
|
||||||
|
T,
|
||||||
|
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
|
||||||
|
::boost::is_empty<T>::value,
|
||||||
|
::boost::is_empty<T>::value>::value>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef details::compressed_pair_imp<T, T,
|
||||||
|
::boost::details::compressed_pair_switch<
|
||||||
|
T,
|
||||||
|
T,
|
||||||
|
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
|
||||||
|
::boost::is_empty<T>::value,
|
||||||
|
::boost::is_empty<T>::value>::value> base;
|
||||||
|
public:
|
||||||
|
typedef T first_type;
|
||||||
|
typedef T second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair() : base() {}
|
||||||
|
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
|
||||||
|
#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
|
||||||
|
explicit
|
||||||
|
#endif
|
||||||
|
compressed_pair(first_param_type x) : base(x) {}
|
||||||
|
|
||||||
|
first_reference first() {return base::first();}
|
||||||
|
first_const_reference first() const {return base::first();}
|
||||||
|
|
||||||
|
second_reference second() {return base::second();}
|
||||||
|
second_const_reference second() const {return base::second();}
|
||||||
|
|
||||||
|
void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||||
|
{
|
||||||
|
x.swap(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // boost
|
||||||
|
|
||||||
|
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||||
|
|
||||||
|
|
||||||
|
|
168
include/boost/detail/ob_call_traits.hpp
Normal file
168
include/boost/detail/ob_call_traits.hpp
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||||
|
// Use, modification and distribution are subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt).
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||||
|
//
|
||||||
|
// Crippled version for crippled compilers:
|
||||||
|
// see libs/utility/call_traits.htm
|
||||||
|
//
|
||||||
|
|
||||||
|
/* Release notes:
|
||||||
|
01st October 2000:
|
||||||
|
Fixed call_traits on VC6, using "poor man's partial specialisation",
|
||||||
|
using ideas taken from "Generative programming" by Krzysztof Czarnecki
|
||||||
|
& Ulrich Eisenecker.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_OB_CALL_TRAITS_HPP
|
||||||
|
#define BOOST_OB_CALL_TRAITS_HPP
|
||||||
|
|
||||||
|
#ifndef BOOST_CONFIG_HPP
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
|
||||||
|
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||||
|
#endif
|
||||||
|
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
|
||||||
|
#include <boost/type_traits/composite_traits.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
||||||
|
//
|
||||||
|
// use member templates to emulate
|
||||||
|
// partial specialisation:
|
||||||
|
//
|
||||||
|
namespace detail{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct standard_call_traits
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const T& param_type;
|
||||||
|
};
|
||||||
|
template <class T>
|
||||||
|
struct simple_call_traits
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const T param_type;
|
||||||
|
};
|
||||||
|
template <class T>
|
||||||
|
struct reference_call_traits
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T reference;
|
||||||
|
typedef T const_reference;
|
||||||
|
typedef T param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool pointer, bool arithmetic, bool reference>
|
||||||
|
struct call_traits_chooser
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef standard_call_traits<T> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct call_traits_chooser<true, false, false>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef simple_call_traits<T> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct call_traits_chooser<false, false, true>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef reference_call_traits<T> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool size_is_small>
|
||||||
|
struct call_traits_sizeof_chooser2
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct small_rebind
|
||||||
|
{
|
||||||
|
typedef simple_call_traits<T> small_type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct call_traits_sizeof_chooser2<false>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct small_rebind
|
||||||
|
{
|
||||||
|
typedef standard_call_traits<T> small_type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct call_traits_chooser<false, true, false>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
|
||||||
|
typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
|
||||||
|
typedef typename chooser::template small_rebind<T> bound_type;
|
||||||
|
typedef typename bound_type::small_type type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef detail::call_traits_chooser<
|
||||||
|
::boost::is_pointer<T>::value,
|
||||||
|
::boost::is_arithmetic<T>::value,
|
||||||
|
::boost::is_reference<T>::value
|
||||||
|
> chooser;
|
||||||
|
typedef typename chooser::template rebind<T> bound_type;
|
||||||
|
typedef typename bound_type::type call_traits_type;
|
||||||
|
public:
|
||||||
|
typedef typename call_traits_type::value_type value_type;
|
||||||
|
typedef typename call_traits_type::reference reference;
|
||||||
|
typedef typename call_traits_type::const_reference const_reference;
|
||||||
|
typedef typename call_traits_type::param_type param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
//
|
||||||
|
// sorry call_traits is completely non-functional
|
||||||
|
// blame your broken compiler:
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct call_traits
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const T& param_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // member templates
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_OB_CALL_TRAITS_HPP
|
510
include/boost/detail/ob_compressed_pair.hpp
Normal file
510
include/boost/detail/ob_compressed_pair.hpp
Normal file
@@ -0,0 +1,510 @@
|
|||||||
|
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||||
|
// Use, modification and distribution are subject to the Boost Software License,
|
||||||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt).
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/utility for most recent version including documentation.
|
||||||
|
// see libs/utility/compressed_pair.hpp
|
||||||
|
//
|
||||||
|
/* Release notes:
|
||||||
|
20 Jan 2001:
|
||||||
|
Fixed obvious bugs (David Abrahams)
|
||||||
|
07 Oct 2000:
|
||||||
|
Added better single argument constructor support.
|
||||||
|
03 Oct 2000:
|
||||||
|
Added VC6 support (JM).
|
||||||
|
23rd July 2000:
|
||||||
|
Additional comments added. (JM)
|
||||||
|
Jan 2000:
|
||||||
|
Original version: this version crippled for use with crippled compilers
|
||||||
|
- John Maddock Jan 2000.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BOOST_OB_COMPRESSED_PAIR_HPP
|
||||||
|
#define BOOST_OB_COMPRESSED_PAIR_HPP
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
|
||||||
|
#include <boost/type_traits/object_traits.hpp>
|
||||||
|
#endif
|
||||||
|
#ifndef BOOST_SAME_TRAITS_HPP
|
||||||
|
#include <boost/type_traits/same_traits.hpp>
|
||||||
|
#endif
|
||||||
|
#ifndef BOOST_CALL_TRAITS_HPP
|
||||||
|
#include <boost/call_traits.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
||||||
|
//
|
||||||
|
// use member templates to emulate
|
||||||
|
// partial specialisation. Note that due to
|
||||||
|
// problems with overload resolution with VC6
|
||||||
|
// each of the compressed_pair versions that follow
|
||||||
|
// have one template single-argument constructor
|
||||||
|
// in place of two specific constructors:
|
||||||
|
//
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair;
|
||||||
|
|
||||||
|
namespace detail{
|
||||||
|
|
||||||
|
template <class A, class T1, class T2>
|
||||||
|
struct best_conversion_traits
|
||||||
|
{
|
||||||
|
typedef char one;
|
||||||
|
typedef char (&two)[2];
|
||||||
|
static A a;
|
||||||
|
static one test(T1);
|
||||||
|
static two test(T2);
|
||||||
|
|
||||||
|
enum { value = sizeof(test(a)) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int>
|
||||||
|
struct init_one;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct init_one<1>
|
||||||
|
{
|
||||||
|
template <class A, class T1, class T2>
|
||||||
|
static void init(const A& a, T1* p1, T2*)
|
||||||
|
{
|
||||||
|
*p1 = a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct init_one<2>
|
||||||
|
{
|
||||||
|
template <class A, class T1, class T2>
|
||||||
|
static void init(const A& a, T1*, T2* p2)
|
||||||
|
{
|
||||||
|
*p2 = a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// T1 != T2, both non-empty
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_0
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T1 _first;
|
||||||
|
T2 _second;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_0() : _first(), _second() {}
|
||||||
|
compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
||||||
|
template <class A>
|
||||||
|
explicit compressed_pair_0(const A& val)
|
||||||
|
{
|
||||||
|
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
|
||||||
|
}
|
||||||
|
compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
|
||||||
|
: _first(x.first()), _second(x.second()) {}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
compressed_pair_0& operator=(const compressed_pair_0& x) {
|
||||||
|
cout << "assigning compressed pair 0" << endl;
|
||||||
|
_first = x._first;
|
||||||
|
_second = x._second;
|
||||||
|
cout << "finished assigning compressed pair 0" << endl;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
first_reference first() { return _first; }
|
||||||
|
first_const_reference first() const { return _first; }
|
||||||
|
|
||||||
|
second_reference second() { return _second; }
|
||||||
|
second_const_reference second() const { return _second; }
|
||||||
|
|
||||||
|
void swap(compressed_pair_0& y)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(_first, y._first);
|
||||||
|
swap(_second, y._second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// T1 != T2, T2 empty
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_1 : T2
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T1 _first;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_1() : T2(), _first() {}
|
||||||
|
compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
|
||||||
|
|
||||||
|
template <class A>
|
||||||
|
explicit compressed_pair_1(const A& val)
|
||||||
|
{
|
||||||
|
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
|
||||||
|
: T2(x.second()), _first(x.first()) {}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
||||||
|
// Total weirdness. If the assignment to _first is moved after
|
||||||
|
// the call to the inherited operator=, then this breaks graph/test/graph.cpp
|
||||||
|
// by way of iterator_adaptor.
|
||||||
|
compressed_pair_1& operator=(const compressed_pair_1& x) {
|
||||||
|
_first = x._first;
|
||||||
|
T2::operator=(x);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
first_reference first() { return _first; }
|
||||||
|
first_const_reference first() const { return _first; }
|
||||||
|
|
||||||
|
second_reference second() { return *this; }
|
||||||
|
second_const_reference second() const { return *this; }
|
||||||
|
|
||||||
|
void swap(compressed_pair_1& y)
|
||||||
|
{
|
||||||
|
// no need to swap empty base class:
|
||||||
|
using std::swap;
|
||||||
|
swap(_first, y._first);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// T1 != T2, T1 empty
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_2 : T1
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T2 _second;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_2() : T1(), _second() {}
|
||||||
|
compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
|
||||||
|
template <class A>
|
||||||
|
explicit compressed_pair_2(const A& val)
|
||||||
|
{
|
||||||
|
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
|
||||||
|
}
|
||||||
|
compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
|
||||||
|
: T1(x.first()), _second(x.second()) {}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
compressed_pair_2& operator=(const compressed_pair_2& x) {
|
||||||
|
cout << "assigning compressed pair 2" << endl;
|
||||||
|
T1::operator=(x);
|
||||||
|
_second = x._second;
|
||||||
|
cout << "finished assigning compressed pair 2" << endl;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
first_reference first() { return *this; }
|
||||||
|
first_const_reference first() const { return *this; }
|
||||||
|
|
||||||
|
second_reference second() { return _second; }
|
||||||
|
second_const_reference second() const { return _second; }
|
||||||
|
|
||||||
|
void swap(compressed_pair_2& y)
|
||||||
|
{
|
||||||
|
// no need to swap empty base class:
|
||||||
|
using std::swap;
|
||||||
|
swap(_second, y._second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// T1 != T2, both empty
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_3 : T1, T2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_3() : T1(), T2() {}
|
||||||
|
compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
|
||||||
|
template <class A>
|
||||||
|
explicit compressed_pair_3(const A& val)
|
||||||
|
{
|
||||||
|
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
|
||||||
|
}
|
||||||
|
compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
|
||||||
|
: T1(x.first()), T2(x.second()) {}
|
||||||
|
|
||||||
|
first_reference first() { return *this; }
|
||||||
|
first_const_reference first() const { return *this; }
|
||||||
|
|
||||||
|
second_reference second() { return *this; }
|
||||||
|
second_const_reference second() const { return *this; }
|
||||||
|
|
||||||
|
void swap(compressed_pair_3& y)
|
||||||
|
{
|
||||||
|
// no need to swap empty base classes:
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// T1 == T2, and empty
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_4 : T1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_4() : T1() {}
|
||||||
|
compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
|
||||||
|
// only one single argument constructor since T1 == T2
|
||||||
|
explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
|
||||||
|
compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
|
||||||
|
: T1(x.first()), m_second(x.second()) {}
|
||||||
|
|
||||||
|
first_reference first() { return *this; }
|
||||||
|
first_const_reference first() const { return *this; }
|
||||||
|
|
||||||
|
second_reference second() { return m_second; }
|
||||||
|
second_const_reference second() const { return m_second; }
|
||||||
|
|
||||||
|
void swap(compressed_pair_4& y)
|
||||||
|
{
|
||||||
|
// no need to swap empty base classes:
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T2 m_second;
|
||||||
|
};
|
||||||
|
|
||||||
|
// T1 == T2, not empty
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair_5
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T1 _first;
|
||||||
|
T2 _second;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair_5() : _first(), _second() {}
|
||||||
|
compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
||||||
|
// only one single argument constructor since T1 == T2
|
||||||
|
explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
|
||||||
|
compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
|
||||||
|
: _first(c.first()), _second(c.second()) {}
|
||||||
|
|
||||||
|
first_reference first() { return _first; }
|
||||||
|
first_const_reference first() const { return _first; }
|
||||||
|
|
||||||
|
second_reference second() { return _second; }
|
||||||
|
second_const_reference second() const { return _second; }
|
||||||
|
|
||||||
|
void swap(compressed_pair_5& y)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(_first, y._first);
|
||||||
|
swap(_second, y._second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool e1, bool e2, bool same>
|
||||||
|
struct compressed_pair_chooser
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef compressed_pair_0<T1, T2> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct compressed_pair_chooser<false, true, false>
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef compressed_pair_1<T1, T2> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct compressed_pair_chooser<true, false, false>
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef compressed_pair_2<T1, T2> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct compressed_pair_chooser<true, true, false>
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef compressed_pair_3<T1, T2> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct compressed_pair_chooser<true, true, true>
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef compressed_pair_4<T1, T2> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct compressed_pair_chooser<false, false, true>
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
typedef compressed_pair_5<T1, T2> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct compressed_pair_traits
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
|
||||||
|
typedef typename chooser::template rebind<T1, T2> bound_type;
|
||||||
|
public:
|
||||||
|
typedef typename bound_type::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair() : base_type() {}
|
||||||
|
compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
|
||||||
|
template <class A>
|
||||||
|
explicit compressed_pair(const A& x) : base_type(x){}
|
||||||
|
|
||||||
|
first_reference first() { return base_type::first(); }
|
||||||
|
first_const_reference first() const { return base_type::first(); }
|
||||||
|
|
||||||
|
second_reference second() { return base_type::second(); }
|
||||||
|
second_const_reference second() const { return base_type::second(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||||
|
{
|
||||||
|
x.swap(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
// no partial specialisation, no member templates:
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
class compressed_pair
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T1 _first;
|
||||||
|
T2 _second;
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||||
|
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||||
|
typedef typename call_traits<first_type>::reference first_reference;
|
||||||
|
typedef typename call_traits<second_type>::reference second_reference;
|
||||||
|
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||||
|
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||||
|
|
||||||
|
compressed_pair() : _first(), _second() {}
|
||||||
|
compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
||||||
|
explicit compressed_pair(first_param_type x) : _first(x), _second() {}
|
||||||
|
// can't define this in case T1 == T2:
|
||||||
|
// explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
|
||||||
|
|
||||||
|
first_reference first() { return _first; }
|
||||||
|
first_const_reference first() const { return _first; }
|
||||||
|
|
||||||
|
second_reference second() { return _second; }
|
||||||
|
second_const_reference second() const { return _second; }
|
||||||
|
|
||||||
|
void swap(compressed_pair& y)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(_first, y._first);
|
||||||
|
swap(_second, y._second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||||
|
{
|
||||||
|
x.swap(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // boost
|
||||||
|
|
||||||
|
#endif // BOOST_OB_COMPRESSED_PAIR_HPP
|
||||||
|
|
||||||
|
|
||||||
|
|
81
include/boost/generator_iterator.hpp
Normal file
81
include/boost/generator_iterator.hpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// (C) Copyright Jens Maurer 2001. Permission to copy, use,
|
||||||
|
// modify, sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
// Revision History:
|
||||||
|
|
||||||
|
// 15 Nov 2001 Jens Maurer
|
||||||
|
// created.
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
|
||||||
|
|
||||||
|
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
|
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<class Generator>
|
||||||
|
class generator_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
generator_iterator<Generator>
|
||||||
|
, typename Generator::result_type
|
||||||
|
, single_pass_traversal_tag
|
||||||
|
, typename Generator::result_type const&
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef iterator_facade<
|
||||||
|
generator_iterator<Generator>
|
||||||
|
, typename Generator::result_type
|
||||||
|
, single_pass_traversal_tag
|
||||||
|
, typename Generator::result_type const&
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
generator_iterator() {}
|
||||||
|
generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
m_value = (*m_g)();
|
||||||
|
}
|
||||||
|
|
||||||
|
const typename Generator::result_type&
|
||||||
|
dereference() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(generator_iterator const& y) const
|
||||||
|
{
|
||||||
|
return this->m_g == y.m_g && this->m_value == y.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Generator* m_g;
|
||||||
|
typename Generator::result_type m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Generator>
|
||||||
|
struct generator_iterator_generator
|
||||||
|
{
|
||||||
|
typedef generator_iterator<Generator> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Generator>
|
||||||
|
inline generator_iterator<Generator>
|
||||||
|
make_generator_iterator(Generator & gen)
|
||||||
|
{
|
||||||
|
typedef generator_iterator<Generator> result_t;
|
||||||
|
return result_t(&gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
|
|
53
include/boost/next_prior.hpp
Normal file
53
include/boost/next_prior.hpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Boost next_prior.hpp header file ---------------------------------------//
|
||||||
|
|
||||||
|
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
||||||
|
// and distribute this software is granted provided this copyright
|
||||||
|
// notice appears in all copies. This software is provided "as is" without
|
||||||
|
// express or implied warranty, and with no claim as to its suitability for
|
||||||
|
// any purpose.
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/utility for documentation.
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 13 Dec 2003 Added next(x, n) and prior(x, n) (Daniel Walker)
|
||||||
|
|
||||||
|
#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
|
||||||
|
#define BOOST_NEXT_PRIOR_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// Helper functions for classes like bidirectional iterators not supporting
|
||||||
|
// operator+ and operator-
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// const std::list<T>::iterator p = get_some_iterator();
|
||||||
|
// const std::list<T>::iterator prev = boost::prior(p);
|
||||||
|
// const std::list<T>::iterator next = boost::next(prev, 2);
|
||||||
|
|
||||||
|
// Contributed by Dave Abrahams
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T next(T x) { return ++x; }
|
||||||
|
|
||||||
|
template <class T, class Distance>
|
||||||
|
inline T next(T x, Distance n)
|
||||||
|
{
|
||||||
|
std::advance(x, n);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T prior(T x) { return --x; }
|
||||||
|
|
||||||
|
template <class T, class Distance>
|
||||||
|
inline T prior(T x, Distance n)
|
||||||
|
{
|
||||||
|
std::advance(x, -n);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED
|
33
include/boost/noncopyable.hpp
Normal file
33
include/boost/noncopyable.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Boost noncopyable.hpp header file --------------------------------------//
|
||||||
|
|
||||||
|
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
||||||
|
// and distribute this software is granted provided this copyright
|
||||||
|
// notice appears in all copies. This software is provided "as is" without
|
||||||
|
// express or implied warranty, and with no claim as to its suitability for
|
||||||
|
// any purpose.
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/utility for documentation.
|
||||||
|
|
||||||
|
#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||||
|
#define BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// Private copy constructor and copy assignment ensure classes derived from
|
||||||
|
// class noncopyable cannot be copied.
|
||||||
|
|
||||||
|
// Contributed by Dave Abrahams
|
||||||
|
|
||||||
|
class noncopyable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
noncopyable() {}
|
||||||
|
~noncopyable() {}
|
||||||
|
private: // emphasize the following members are private
|
||||||
|
noncopyable( const noncopyable& );
|
||||||
|
const noncopyable& operator=( const noncopyable& );
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_NONCOPYABLE_HPP_INCLUDED
|
@@ -1,20 +1,32 @@
|
|||||||
// Boost operators.hpp header file ----------------------------------------//
|
// Boost operators.hpp header file ----------------------------------------//
|
||||||
|
|
||||||
// (C) Copyright David Abrahams 1999. Permission to copy, use,
|
// (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
|
||||||
// modify, sell and distribute this software is granted provided this
|
// Permission to copy, use, modify, sell and distribute this software is
|
||||||
// copyright notice appears in all copies. This software is provided
|
// granted provided this copyright notice appears in all copies. This
|
||||||
// "as is" without express or implied warranty, and with no claim as
|
// software is provided "as is" without express or implied warranty, and
|
||||||
// to its suitability for any purpose.
|
// with no claim as to its suitability for any purpose.
|
||||||
|
|
||||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||||
// sell and distribute this software is granted provided this
|
|
||||||
// copyright notice appears in all copies. This software is provided
|
|
||||||
// "as is" without express or implied warranty, and with no claim as
|
|
||||||
// to its suitability for any purpose.
|
|
||||||
|
|
||||||
// See http://www.boost.org for most recent version including documentation.
|
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
|
// 21 Oct 02 Modified implementation of operators to allow compilers with a
|
||||||
|
// correct named return value optimization (NRVO) to produce optimal
|
||||||
|
// code. (Daniel Frey)
|
||||||
|
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
|
||||||
|
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
|
||||||
|
// 27 Aug 01 'left' form for non commutative operators added;
|
||||||
|
// additional classes for groups of related operators added;
|
||||||
|
// workaround for empty base class optimization
|
||||||
|
// bug of GCC 3.0 (Helmut Zeisel)
|
||||||
|
// 25 Jun 01 output_iterator_helper changes: removed default template
|
||||||
|
// parameters, added support for self-proxying, additional
|
||||||
|
// documentation and tests (Aleksey Gurtovoy)
|
||||||
|
// 29 May 01 Added operator classes for << and >>. Added input and output
|
||||||
|
// iterator helper classes. Added classes to connect equality and
|
||||||
|
// relational operators. Added classes for groups of related
|
||||||
|
// operators. Reimplemented example operator and iterator helper
|
||||||
|
// classes in terms of the new groups. (Daryle Walker, with help
|
||||||
|
// from Alexy Gurtovoy)
|
||||||
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
|
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
|
||||||
// supplied arguments from actually being used (Dave Abrahams)
|
// supplied arguments from actually being used (Dave Abrahams)
|
||||||
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
||||||
@@ -66,9 +78,10 @@
|
|||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
#pragma set woff 1234
|
# pragma set woff 1234
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
@@ -78,7 +91,14 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
|
||||||
|
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
|
||||||
|
class empty_base {
|
||||||
|
bool dummy;
|
||||||
|
};
|
||||||
|
#else
|
||||||
class empty_base {};
|
class empty_base {};
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
@@ -133,106 +153,112 @@ struct equality_comparable1 : B
|
|||||||
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
|
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
// A macro which produces "name_2left" from "name".
|
||||||
struct multipliable2 : B
|
#define BOOST_OPERATOR2_LEFT(name) name##2##_##left
|
||||||
{
|
|
||||||
friend T operator*(T x, const U& y) { return x *= y; }
|
// NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
|
||||||
friend T operator*(const U& y, T x) { return x *= y; }
|
|
||||||
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
// This is the optimal implementation for ISO/ANSI C++,
|
||||||
|
// but it requires the compiler to implement the NRVO.
|
||||||
|
// If the compiler has no NRVO, this is the best symmetric
|
||||||
|
// implementation available.
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
struct multipliable1 : B
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
{
|
struct NAME##2 : B \
|
||||||
friend T operator*(T x, const T& y) { return x *= y; }
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
struct addable2 : B
|
|
||||||
{
|
// For compilers without NRVO the following code is optimal, but not
|
||||||
friend T operator+(T x, const U& y) { return x += y; }
|
// symmetric! Note that the implementation of
|
||||||
friend T operator+(const U& y, T x) { return x += y; }
|
// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
|
||||||
|
// optimization opportunities to the compiler :)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
struct addable1 : B
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
{
|
struct NAME##2 : B \
|
||||||
friend T operator+(T x, const T& y) { return x += y; }
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ return T( lhs ) OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
struct subtractable2 : B
|
|
||||||
{
|
|
||||||
friend T operator-(T x, const U& y) { return x -= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
|
||||||
struct subtractable1 : B
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
|
||||||
{
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
|
||||||
friend T operator-(T x, const T& y) { return x -= y; }
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
|
||||||
};
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
|
||||||
struct dividable2 : B
|
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
|
||||||
{
|
#undef BOOST_OPERATOR2_LEFT
|
||||||
friend T operator/(T x, const U& y) { return x /= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
|
||||||
struct dividable1 : B
|
|
||||||
{
|
|
||||||
friend T operator/(T x, const T& y) { return x /= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
|
||||||
struct modable2 : B
|
|
||||||
{
|
|
||||||
friend T operator%(T x, const U& y) { return x %= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
|
||||||
struct modable1 : B
|
|
||||||
{
|
|
||||||
friend T operator%(T x, const T& y) { return x %= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
|
||||||
struct xorable2 : B
|
|
||||||
{
|
|
||||||
friend T operator^(T x, const U& y) { return x ^= y; }
|
|
||||||
friend T operator^(const U& y, T x) { return x ^= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
|
||||||
struct xorable1 : B
|
|
||||||
{
|
|
||||||
friend T operator^(T x, const T& y) { return x ^= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
|
||||||
struct andable2 : B
|
|
||||||
{
|
|
||||||
friend T operator&(T x, const U& y) { return x &= y; }
|
|
||||||
friend T operator&(const U& y, T x) { return x &= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
|
||||||
struct andable1 : B
|
|
||||||
{
|
|
||||||
friend T operator&(T x, const T& y) { return x &= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
|
||||||
struct orable2 : B
|
|
||||||
{
|
|
||||||
friend T operator|(T x, const U& y) { return x |= y; }
|
|
||||||
friend T operator|(const U& y, T x) { return x |= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base>
|
|
||||||
struct orable1 : B
|
|
||||||
{
|
|
||||||
friend T operator|(T x, const T& y) { return x |= y; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// incrementable and decrementable contributed by Jeremy Siek
|
// incrementable and decrementable contributed by Jeremy Siek
|
||||||
|
|
||||||
@@ -241,9 +267,9 @@ struct incrementable : B
|
|||||||
{
|
{
|
||||||
friend T operator++(T& x, int)
|
friend T operator++(T& x, int)
|
||||||
{
|
{
|
||||||
incrementable_type tmp(x);
|
incrementable_type nrv(x);
|
||||||
++x;
|
++x;
|
||||||
return tmp;
|
return nrv;
|
||||||
}
|
}
|
||||||
private: // The use of this typedef works around a Borland bug
|
private: // The use of this typedef works around a Borland bug
|
||||||
typedef T incrementable_type;
|
typedef T incrementable_type;
|
||||||
@@ -254,9 +280,9 @@ struct decrementable : B
|
|||||||
{
|
{
|
||||||
friend T operator--(T& x, int)
|
friend T operator--(T& x, int)
|
||||||
{
|
{
|
||||||
decrementable_type tmp(x);
|
decrementable_type nrv(x);
|
||||||
--x;
|
--x;
|
||||||
return tmp;
|
return nrv;
|
||||||
}
|
}
|
||||||
private: // The use of this typedef works around a Borland bug
|
private: // The use of this typedef works around a Borland bug
|
||||||
typedef T decrementable_type;
|
typedef T decrementable_type;
|
||||||
@@ -282,12 +308,319 @@ struct indexable : B
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// More operator classes (contributed by Daryle Walker) --------------------//
|
||||||
|
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
BOOST_BINARY_OPERATOR( left_shiftable, << )
|
||||||
|
BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
||||||
|
|
||||||
|
#undef BOOST_BINARY_OPERATOR
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct equivalent2 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const T& x, const U& y)
|
||||||
|
{
|
||||||
|
return !(x < y) && !(x > y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct equivalent1 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const T&x, const T&y)
|
||||||
|
{
|
||||||
|
return !(x < y) && !(y < x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct partially_ordered2 : B
|
||||||
|
{
|
||||||
|
friend bool operator<=(const T& x, const U& y)
|
||||||
|
{ return (x < y) || (x == y); }
|
||||||
|
friend bool operator>=(const T& x, const U& y)
|
||||||
|
{ return (x > y) || (x == y); }
|
||||||
|
friend bool operator>(const U& x, const T& y)
|
||||||
|
{ return y < x; }
|
||||||
|
friend bool operator<(const U& x, const T& y)
|
||||||
|
{ return y > x; }
|
||||||
|
friend bool operator<=(const U& x, const T& y)
|
||||||
|
{ return (y > x) || (y == x); }
|
||||||
|
friend bool operator>=(const U& x, const T& y)
|
||||||
|
{ return (y < x) || (y == x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct partially_ordered1 : B
|
||||||
|
{
|
||||||
|
friend bool operator>(const T& x, const T& y)
|
||||||
|
{ return y < x; }
|
||||||
|
friend bool operator<=(const T& x, const T& y)
|
||||||
|
{ return (x < y) || (x == y); }
|
||||||
|
friend bool operator>=(const T& x, const T& y)
|
||||||
|
{ return (y < x) || (x == y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct totally_ordered2
|
||||||
|
: less_than_comparable2<T, U
|
||||||
|
, equality_comparable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct totally_ordered1
|
||||||
|
: less_than_comparable1<T
|
||||||
|
, equality_comparable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct additive2
|
||||||
|
: addable2<T, U
|
||||||
|
, subtractable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct additive1
|
||||||
|
: addable1<T
|
||||||
|
, subtractable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct multiplicative2
|
||||||
|
: multipliable2<T, U
|
||||||
|
, dividable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct multiplicative1
|
||||||
|
: multipliable1<T
|
||||||
|
, dividable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct integer_multiplicative2
|
||||||
|
: multiplicative2<T, U
|
||||||
|
, modable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct integer_multiplicative1
|
||||||
|
: multiplicative1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct arithmetic2
|
||||||
|
: additive2<T, U
|
||||||
|
, multiplicative2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct arithmetic1
|
||||||
|
: additive1<T
|
||||||
|
, multiplicative1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct integer_arithmetic2
|
||||||
|
: additive2<T, U
|
||||||
|
, integer_multiplicative2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct integer_arithmetic1
|
||||||
|
: additive1<T
|
||||||
|
, integer_multiplicative1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct bitwise2
|
||||||
|
: xorable2<T, U
|
||||||
|
, andable2<T, U
|
||||||
|
, orable2<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct bitwise1
|
||||||
|
: xorable1<T
|
||||||
|
, andable1<T
|
||||||
|
, orable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct unit_steppable
|
||||||
|
: incrementable<T
|
||||||
|
, decrementable<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct shiftable2
|
||||||
|
: left_shiftable2<T, U
|
||||||
|
, right_shiftable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct shiftable1
|
||||||
|
: left_shiftable1<T
|
||||||
|
, right_shiftable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct ring_operators2
|
||||||
|
: additive2<T, U
|
||||||
|
, subtractable2_left<T, U
|
||||||
|
, multipliable2<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct ring_operators1
|
||||||
|
: additive1<T
|
||||||
|
, multipliable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct ordered_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, totally_ordered2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct ordered_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, totally_ordered1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct field_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct field_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct ordered_field_operators2
|
||||||
|
: field_operators2<T, U
|
||||||
|
, totally_ordered2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct ordered_field_operators1
|
||||||
|
: field_operators1<T
|
||||||
|
, totally_ordered1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct euclidian_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U
|
||||||
|
, modable2<T, U
|
||||||
|
, modable2_left<T, U, B
|
||||||
|
> > > > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct euclidian_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct ordered_euclidian_ring_operators2
|
||||||
|
: totally_ordered2<T, U
|
||||||
|
, euclidian_ring_operators2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct ordered_euclidian_ring_operators1
|
||||||
|
: totally_ordered1<T
|
||||||
|
, euclidian_ring_operators1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base>
|
||||||
|
struct input_iteratable
|
||||||
|
: equality_comparable1<T
|
||||||
|
, incrementable<T
|
||||||
|
, dereferenceable<T, P, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct output_iteratable
|
||||||
|
: incrementable<T, B
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base>
|
||||||
|
struct forward_iteratable
|
||||||
|
: input_iteratable<T, P, B
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base>
|
||||||
|
struct bidirectional_iteratable
|
||||||
|
: forward_iteratable<T, P
|
||||||
|
, decrementable<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
// To avoid repeated derivation from equality_comparable,
|
||||||
|
// which is an indirect base class of bidirectional_iterable,
|
||||||
|
// random_access_iteratable must not be derived from totally_ordered1
|
||||||
|
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
||||||
|
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base>
|
||||||
|
struct random_access_iteratable
|
||||||
|
: bidirectional_iteratable<T, P
|
||||||
|
, less_than_comparable1<T
|
||||||
|
, additive2<T, D
|
||||||
|
, indexable<T, D, R, B
|
||||||
|
> > > > {};
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
// BOOST_IMPORT_TEMPLATE1/BOOST_IMPORT_TEMPLATE2 -
|
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
|
||||||
//
|
//
|
||||||
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
||||||
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
||||||
@@ -295,12 +628,37 @@ struct indexable : B
|
|||||||
// two-argument forms. Note that these macros expect to be invoked from within
|
// two-argument forms. Note that these macros expect to be invoked from within
|
||||||
// boost.
|
// boost.
|
||||||
|
|
||||||
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE)
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
# if defined(BOOST_NO_USING_TEMPLATE)
|
// The template is already in boost so we have nothing to do.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
||||||
|
|
||||||
|
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
# ifndef BOOST_NO_USING_TEMPLATE
|
||||||
|
|
||||||
|
// Bring the names in with a using-declaration
|
||||||
|
// to avoid stressing the compiler.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
|
||||||
|
// from working, we are forced to use inheritance for that compiler.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name) \
|
||||||
|
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base> \
|
||||||
|
struct template_name : ::template_name<T, U, V, W, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name) \
|
||||||
|
template <class T, class U, class V, class B = ::boost::detail::empty_base> \
|
||||||
|
struct template_name : ::template_name<T, U, V, B> {};
|
||||||
|
|
||||||
// Because a Borland C++ 5.5 bug prevents a using declaration from working,
|
|
||||||
// we are forced to use inheritance for that compiler.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
struct template_name : ::template_name<T, U, B> {};
|
struct template_name : ::template_name<T, U, B> {};
|
||||||
@@ -309,21 +667,8 @@ struct indexable : B
|
|||||||
template <class T, class B = ::boost::detail::empty_base> \
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
struct template_name : ::template_name<T, B> {};
|
struct template_name : ::template_name<T, B> {};
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
// Otherwise, bring the names in with a using-declaration to avoid
|
|
||||||
// stressing the compiler
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
|
||||||
|
|
||||||
# endif // BOOST_NO_USING_TEMPLATE
|
# endif // BOOST_NO_USING_TEMPLATE
|
||||||
|
|
||||||
#else // !BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
// The template is already in boost so we have nothing to do.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
|
||||||
|
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -332,7 +677,7 @@ struct indexable : B
|
|||||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
||||||
// neccessary.
|
// neccessary.
|
||||||
//
|
//
|
||||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
// is_chained_base<> - a traits class used to distinguish whether an operator
|
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||||
// template argument is being used for base class chaining, or is specifying a
|
// template argument is being used for base class chaining, or is specifying a
|
||||||
@@ -355,6 +700,24 @@ template<class T> struct is_chained_base {
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
// Import a 4-type-argument operator template into boost (if neccessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||||
|
BOOST_IMPORT_TEMPLATE4(template_name4) \
|
||||||
|
template<class T, class U, class V, class W, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 3-type-argument operator template into boost (if neccessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||||
|
BOOST_IMPORT_TEMPLATE3(template_name3) \
|
||||||
|
template<class T, class U, class V, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
// Import a 2-type-argument operator template into boost (if neccessary) and
|
// Import a 2-type-argument operator template into boost (if neccessary) and
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
@@ -414,6 +777,10 @@ BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
|||||||
|
|
||||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||||
|
BOOST_IMPORT_TEMPLATE4(template_name4)
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||||
|
BOOST_IMPORT_TEMPLATE3(template_name3)
|
||||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
BOOST_IMPORT_TEMPLATE2(template_name2)
|
BOOST_IMPORT_TEMPLATE2(template_name2)
|
||||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||||
@@ -434,55 +801,65 @@ BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
|||||||
BOOST_OPERATOR_TEMPLATE(multipliable)
|
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||||
BOOST_OPERATOR_TEMPLATE(addable)
|
BOOST_OPERATOR_TEMPLATE(addable)
|
||||||
BOOST_OPERATOR_TEMPLATE(subtractable)
|
BOOST_OPERATOR_TEMPLATE(subtractable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
|
||||||
BOOST_OPERATOR_TEMPLATE(dividable)
|
BOOST_OPERATOR_TEMPLATE(dividable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
|
||||||
BOOST_OPERATOR_TEMPLATE(modable)
|
BOOST_OPERATOR_TEMPLATE(modable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(modable2_left)
|
||||||
BOOST_OPERATOR_TEMPLATE(xorable)
|
BOOST_OPERATOR_TEMPLATE(xorable)
|
||||||
BOOST_OPERATOR_TEMPLATE(andable)
|
BOOST_OPERATOR_TEMPLATE(andable)
|
||||||
BOOST_OPERATOR_TEMPLATE(orable)
|
BOOST_OPERATOR_TEMPLATE(orable)
|
||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
||||||
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE3(indexable)
|
||||||
|
|
||||||
// indexable doesn't follow the patterns above (it has 4 template arguments), so
|
BOOST_OPERATOR_TEMPLATE(left_shiftable)
|
||||||
// we just write out the compiler hacks explicitly.
|
BOOST_OPERATOR_TEMPLATE(right_shiftable)
|
||||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
BOOST_OPERATOR_TEMPLATE(equivalent)
|
||||||
# ifdef BOOST_NO_USING_TEMPLATE
|
BOOST_OPERATOR_TEMPLATE(partially_ordered)
|
||||||
template <class T, class I, class R, class B = ::boost::detail::empty_base>
|
|
||||||
struct indexable : ::indexable<T,I,R,B> {};
|
|
||||||
# else
|
|
||||||
using ::indexable;
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
BOOST_OPERATOR_TEMPLATE(totally_ordered)
|
||||||
template <class T, class I, class R, class B>
|
BOOST_OPERATOR_TEMPLATE(additive)
|
||||||
struct is_chained_base< ::boost::indexable<T, I, R, B> > {
|
BOOST_OPERATOR_TEMPLATE(multiplicative)
|
||||||
typedef ::boost::detail::true_t operator_template_type;
|
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
|
||||||
};
|
BOOST_OPERATOR_TEMPLATE(arithmetic)
|
||||||
#endif
|
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(bitwise)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(field_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
|
||||||
|
|
||||||
#undef BOOST_OPERATOR_TEMPLATE
|
#undef BOOST_OPERATOR_TEMPLATE
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE4
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE3
|
||||||
#undef BOOST_OPERATOR_TEMPLATE2
|
#undef BOOST_OPERATOR_TEMPLATE2
|
||||||
#undef BOOST_OPERATOR_TEMPLATE1
|
#undef BOOST_OPERATOR_TEMPLATE1
|
||||||
#undef BOOST_IMPORT_TEMPLATE1
|
#undef BOOST_IMPORT_TEMPLATE1
|
||||||
#undef BOOST_IMPORT_TEMPLATE2
|
#undef BOOST_IMPORT_TEMPLATE2
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE3
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE4
|
||||||
|
|
||||||
// The following 'operators' classes can only be used portably if the derived class
|
// The following 'operators' classes can only be used portably if the derived class
|
||||||
// declares ALL of the required member operators.
|
// declares ALL of the required member operators.
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
struct operators2
|
struct operators2
|
||||||
: less_than_comparable2<T,U
|
: totally_ordered2<T,U
|
||||||
, equality_comparable2<T,U
|
, integer_arithmetic2<T,U
|
||||||
, addable2<T,U
|
, bitwise2<T,U
|
||||||
, subtractable2<T,U
|
> > > {};
|
||||||
, multipliable2<T,U
|
|
||||||
, dividable2<T,U
|
|
||||||
, modable2<T,U
|
|
||||||
, orable2<T,U
|
|
||||||
, andable2<T,U
|
|
||||||
, xorable2<T,U
|
|
||||||
> > > > > > > > > > {};
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
template <class T, class U = T>
|
template <class T, class U = T>
|
||||||
@@ -492,32 +869,44 @@ template <class T> struct operators<T, T>
|
|||||||
#else
|
#else
|
||||||
template <class T> struct operators
|
template <class T> struct operators
|
||||||
#endif
|
#endif
|
||||||
: less_than_comparable<T
|
: totally_ordered<T
|
||||||
, equality_comparable<T
|
, integer_arithmetic<T
|
||||||
, addable<T
|
, bitwise<T
|
||||||
, subtractable<T
|
, unit_steppable<T
|
||||||
, multipliable<T
|
> > > > {};
|
||||||
, dividable<T
|
|
||||||
, modable<T
|
|
||||||
, orable<T
|
|
||||||
, andable<T
|
|
||||||
, xorable<T
|
|
||||||
, incrementable<T
|
|
||||||
, decrementable<T
|
|
||||||
> > > > > > > > > > > > {};
|
|
||||||
|
|
||||||
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
||||||
|
// (Input and output iterator helpers contributed by Daryle Walker) -------//
|
||||||
|
// (Changed to use combined operator classes by Daryle Walker) ------------//
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V const *,
|
||||||
|
class R = V const &>
|
||||||
|
struct input_iterator_helper
|
||||||
|
: input_iteratable<T, P
|
||||||
|
, boost::iterator<std::input_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct output_iterator_helper
|
||||||
|
: output_iteratable<T
|
||||||
|
, boost::iterator<std::output_iterator_tag, void, void, void, void
|
||||||
|
> >
|
||||||
|
{
|
||||||
|
T& operator*() { return static_cast<T&>(*this); }
|
||||||
|
T& operator++() { return static_cast<T&>(*this); }
|
||||||
|
};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
class D = std::ptrdiff_t,
|
class D = std::ptrdiff_t,
|
||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct forward_iterator_helper
|
struct forward_iterator_helper
|
||||||
: equality_comparable<T
|
: forward_iteratable<T, P
|
||||||
, incrementable<T
|
, boost::iterator<std::forward_iterator_tag, V, D, P, R
|
||||||
, dereferenceable<T,P
|
> > {};
|
||||||
, boost::iterator<std::forward_iterator_tag,V,D,P,R
|
|
||||||
> > > > {};
|
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
@@ -525,12 +914,9 @@ template <class T,
|
|||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct bidirectional_iterator_helper
|
struct bidirectional_iterator_helper
|
||||||
: equality_comparable<T
|
: bidirectional_iteratable<T, P
|
||||||
, incrementable<T
|
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
||||||
, decrementable<T
|
> > {};
|
||||||
, dereferenceable<T,P
|
|
||||||
, boost::iterator<std::bidirectional_iterator_tag,V,D,P,R
|
|
||||||
> > > > > {};
|
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
@@ -538,22 +924,13 @@ template <class T,
|
|||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct random_access_iterator_helper
|
struct random_access_iterator_helper
|
||||||
: equality_comparable<T
|
: random_access_iteratable<T, P, D, R
|
||||||
, less_than_comparable<T
|
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
|
||||||
, incrementable<T
|
> >
|
||||||
, decrementable<T
|
|
||||||
, dereferenceable<T,P
|
|
||||||
, addable2<T,D
|
|
||||||
, subtractable2<T,D
|
|
||||||
, indexable<T,D,R
|
|
||||||
, boost::iterator<std::random_access_iterator_tag,V,D,P,R
|
|
||||||
> > > > > > > > >
|
|
||||||
{
|
{
|
||||||
#ifndef __BORLANDC__
|
|
||||||
friend D requires_difference_operator(const T& x, const T& y) {
|
friend D requires_difference_operator(const T& x, const T& y) {
|
||||||
return x - y;
|
return x - y;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}; // random_access_iterator_helper
|
}; // random_access_iterator_helper
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
165
include/boost/ref.hpp
Normal file
165
include/boost/ref.hpp
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
#ifndef BOOST_REF_HPP_INCLUDED
|
||||||
|
#define BOOST_REF_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/utility/addressof.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
// ref.hpp - ref/cref, useful helper functions
|
||||||
|
//
|
||||||
|
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
|
||||||
|
// Copyright (C) 2001, 2002 Peter Dimov
|
||||||
|
// Copyright (C) 2002 David Abrahams
|
||||||
|
//
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/bind/ref.html for documentation.
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class T> class reference_wrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T type;
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||||
|
|
||||||
|
explicit reference_wrapper(T& t): t_(&t) {}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
operator T& () const { return *t_; }
|
||||||
|
|
||||||
|
T& get() const { return *t_; }
|
||||||
|
|
||||||
|
T* get_pointer() const { return t_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
T* t_;
|
||||||
|
};
|
||||||
|
|
||||||
|
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)
|
||||||
|
# define BOOST_REF_CONST
|
||||||
|
# else
|
||||||
|
# define BOOST_REF_CONST const
|
||||||
|
# endif
|
||||||
|
|
||||||
|
template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t)
|
||||||
|
{
|
||||||
|
return reference_wrapper<T>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t)
|
||||||
|
{
|
||||||
|
return reference_wrapper<T const>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
# undef BOOST_REF_CONST
|
||||||
|
|
||||||
|
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
template<typename T>
|
||||||
|
class is_reference_wrapper
|
||||||
|
: public mpl::false_
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class is_reference_wrapper<reference_wrapper<T> >
|
||||||
|
: public mpl::true_
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class unwrap_reference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class unwrap_reference<reference_wrapper<T> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
# else // no partial specialization
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/type.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
typedef char (&yes_reference_wrapper_t)[1];
|
||||||
|
typedef char (&no_reference_wrapper_t)[2];
|
||||||
|
|
||||||
|
no_reference_wrapper_t is_reference_wrapper_test(...);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >);
|
||||||
|
|
||||||
|
template<bool wrapped>
|
||||||
|
struct reference_unwrapper
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct apply
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct reference_unwrapper<true>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct apply
|
||||||
|
{
|
||||||
|
typedef typename T::type type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class is_reference_wrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
bool, value = (
|
||||||
|
sizeof(detail::is_reference_wrapper_test(type<T>()))
|
||||||
|
== sizeof(detail::yes_reference_wrapper_t)));
|
||||||
|
|
||||||
|
typedef ::boost::mpl::bool_<value> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class unwrap_reference
|
||||||
|
: public detail::reference_unwrapper<
|
||||||
|
is_reference_wrapper<T>::value
|
||||||
|
>::template apply<T>
|
||||||
|
{};
|
||||||
|
|
||||||
|
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_REF_HPP_INCLUDED
|
19
include/boost/utility.hpp
Normal file
19
include/boost/utility.hpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// Boost utility.hpp header file -------------------------------------------//
|
||||||
|
|
||||||
|
// Copyright 1999-2003 Boost.org. Use, modification, and distribution are
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||||
|
|
||||||
|
// See <http://www.boost.org/libs/utility/> for the library's home page.
|
||||||
|
|
||||||
|
#ifndef BOOST_UTILITY_HPP
|
||||||
|
#define BOOST_UTILITY_HPP
|
||||||
|
|
||||||
|
#include <boost/utility/addressof.hpp>
|
||||||
|
#include <boost/utility/base_from_member.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
#include <boost/checked_delete.hpp>
|
||||||
|
#include <boost/next_prior.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_UTILITY_HPP
|
43
include/boost/utility/addressof.hpp
Normal file
43
include/boost/utility/addressof.hpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
|
||||||
|
// Doug Gregor (gregod@cs.rpi.edu)
|
||||||
|
// Peter Dimov
|
||||||
|
//
|
||||||
|
// Permission to copy, use, sell and distribute this software is granted
|
||||||
|
// provided this copyright notice appears in all copies.
|
||||||
|
// Permission to modify the code and to distribute modified code is granted
|
||||||
|
// provided this copyright notice appears in all copies, and a notice
|
||||||
|
// that the code was modified is included with the copyright notice.
|
||||||
|
//
|
||||||
|
// This software is provided "as is" without express or implied warranty,
|
||||||
|
// and with no claim as to its suitability for any purpose.
|
||||||
|
|
||||||
|
// For more information, see http://www.boost.org
|
||||||
|
|
||||||
|
#ifndef BOOST_UTILITY_ADDRESSOF_HPP
|
||||||
|
# define BOOST_UTILITY_ADDRESSOF_HPP
|
||||||
|
|
||||||
|
# include <boost/config.hpp>
|
||||||
|
# include <boost/detail/workaround.hpp>
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||||
|
# include <boost/type_traits/add_pointer.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
|
||||||
|
|
||||||
|
// VC7 strips const from nested classes unless we add indirection here
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||||
|
template <typename T> typename add_pointer<T>::type
|
||||||
|
# else
|
||||||
|
template <typename T> T*
|
||||||
|
# endif
|
||||||
|
addressof(T& v)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(
|
||||||
|
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_UTILITY_ADDRESSOF_HPP
|
99
include/boost/utility/base_from_member.hpp
Normal file
99
include/boost/utility/base_from_member.hpp
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
// boost utility/base_from_member.hpp header file --------------------------//
|
||||||
|
|
||||||
|
// Copyright 2001, 2003 Daryle Walker. Use, modification, and distribution are
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||||
|
|
||||||
|
// See <http://www.boost.org/libs/utility/> for the library's home page.
|
||||||
|
|
||||||
|
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||||
|
#define BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||||
|
|
||||||
|
#include <boost/utility_fwd.hpp> // required for parameter defaults
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
// Base-from-member class template -----------------------------------------//
|
||||||
|
|
||||||
|
// Helper to initialize a base object so a derived class can use this
|
||||||
|
// object in the initialization of another base class. Used by
|
||||||
|
// Dietmar Kuehl from ideas by Ron Klatcho to solve the problem of a
|
||||||
|
// base class needing to be initialized by a member.
|
||||||
|
|
||||||
|
// Contributed by Daryle Walker
|
||||||
|
|
||||||
|
template < typename MemberType, int UniqueID >
|
||||||
|
class base_from_member
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
MemberType member;
|
||||||
|
|
||||||
|
base_from_member()
|
||||||
|
: member()
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1 >
|
||||||
|
explicit base_from_member( T1 x1 )
|
||||||
|
: member( x1 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2 >
|
||||||
|
base_from_member( T1 x1, T2 x2 )
|
||||||
|
: member( x1, x2 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3 )
|
||||||
|
: member( x1, x2, x3 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4 )
|
||||||
|
: member( x1, x2, x3, x4 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4, typename T5 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5 )
|
||||||
|
: member( x1, x2, x3, x4, x5 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
|
typename T6 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6 )
|
||||||
|
: member( x1, x2, x3, x4, x5, x6 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
|
typename T6, typename T7 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7 )
|
||||||
|
: member( x1, x2, x3, x4, x5, x6, x7 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
|
typename T6, typename T7, typename T8 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8 )
|
||||||
|
: member( x1, x2, x3, x4, x5, x6, x7, x8 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
|
typename T6, typename T7, typename T8, typename T9 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8,
|
||||||
|
T9 x9 )
|
||||||
|
: member( x1, x2, x3, x4, x5, x6, x7, x8, x9 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
|
typename T6, typename T7, typename T8, typename T9, typename T10 >
|
||||||
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8,
|
||||||
|
T9 x9, T10 x10 )
|
||||||
|
: member( x1, x2, x3, x4, x5, x6, x7, x8, x9, x10 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
}; // boost::base_from_member
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
68
include/boost/utility/compare_pointees.hpp
Normal file
68
include/boost/utility/compare_pointees.hpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||||
|
//
|
||||||
|
// Use, modification, and distribution is subject to the Boost Software
|
||||||
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/lib/optional for documentation.
|
||||||
|
//
|
||||||
|
// You are welcome to contact the author at:
|
||||||
|
// fernando_cacciola@hotmail.com
|
||||||
|
//
|
||||||
|
#ifndef BOOST_UTILITY_COMPARE_POINTEES_25AGO2003_HPP
|
||||||
|
#define BOOST_UTILITY_COMPARE_POINTEES_25AGO2003_HPP
|
||||||
|
|
||||||
|
#include<functional>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// template<class OP> bool equal_pointees(OP const& x, OP const& y);
|
||||||
|
// template<class OP> struct equal_pointees_t;
|
||||||
|
//
|
||||||
|
// Being OP a model of OptionalPointee (either a pointer or an optional):
|
||||||
|
//
|
||||||
|
// If both x and y have valid pointees, returns the result of (*x == *y)
|
||||||
|
// If only one has a valid pointee, returns false.
|
||||||
|
// If none have valid pointees, returns true.
|
||||||
|
// No-throw
|
||||||
|
template<class OptionalPointee>
|
||||||
|
inline
|
||||||
|
bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y )
|
||||||
|
{
|
||||||
|
return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OptionalPointee>
|
||||||
|
struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
|
||||||
|
{
|
||||||
|
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
|
||||||
|
{ return equal_pointees(x,y) ; }
|
||||||
|
} ;
|
||||||
|
|
||||||
|
// template<class OP> bool less_pointees(OP const& x, OP const& y);
|
||||||
|
// template<class OP> struct less_pointees_t;
|
||||||
|
//
|
||||||
|
// Being OP a model of OptionalPointee (either a pointer or an optional):
|
||||||
|
//
|
||||||
|
// If y has not a valid pointee, returns false.
|
||||||
|
// ElseIf x has not a valid pointee, returns true.
|
||||||
|
// ElseIf both x and y have valid pointees, returns the result of (*x < *y)
|
||||||
|
// No-throw
|
||||||
|
template<class OptionalPointee>
|
||||||
|
inline
|
||||||
|
bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y )
|
||||||
|
{
|
||||||
|
return !y ? false : ( !x ? true : (*x) < (*y) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OptionalPointee>
|
||||||
|
struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
|
||||||
|
{
|
||||||
|
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
|
||||||
|
{ return less_pointees(x,y) ; }
|
||||||
|
} ;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
78
include/boost/utility/detail/result_of_iterate.hpp
Normal file
78
include/boost/utility/detail/result_of_iterate.hpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#if !defined(BOOST_PP_IS_ITERATING)
|
||||||
|
# error Boost result_of - do not include this file!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// CWPro8 requires an argument in a function type specialization
|
||||||
|
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
|
||||||
|
# define BOOST_RESULT_OF_ARGS void
|
||||||
|
#else
|
||||||
|
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||||
|
: detail::result_of<F, F(BOOST_RESULT_OF_ARGS)> {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<R (*)(BOOST_RESULT_OF_ARGS), FArgs>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<R (&)(BOOST_RESULT_OF_ARGS), FArgs>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef BOOST_RESULT_OF_ARGS
|
||||||
|
|
||||||
|
#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<R (T0::*)
|
||||||
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||||
|
FArgs>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<R (T0::*)
|
||||||
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
|
const,
|
||||||
|
FArgs>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<R (T0::*)
|
||||||
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
|
volatile,
|
||||||
|
FArgs>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<R (T0::*)
|
||||||
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
|
const volatile,
|
||||||
|
FArgs>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
119
include/boost/utility/enable_if.hpp
Normal file
119
include/boost/utility/enable_if.hpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
// Boost enable_if library
|
||||||
|
|
||||||
|
// Copyright 2003 <20> The Trustees of Indiana University.
|
||||||
|
|
||||||
|
// Use, modification, and distribution is subject to the Boost Software
|
||||||
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
|
||||||
|
// Jeremiah Willcock (jewillco at osl.iu.edu)
|
||||||
|
// Andrew Lumsdaine (lums at osl.iu.edu)
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BOOST_UTILITY_ENABLE_IF_HPP
|
||||||
|
#define BOOST_UTILITY_ENABLE_IF_HPP
|
||||||
|
|
||||||
|
#include "boost/config.hpp"
|
||||||
|
|
||||||
|
// Even the definition of enable_if causes problems on some compilers,
|
||||||
|
// so it's macroed out for all compilers that do not support SFINAE
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_SFINAE
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template <bool B, class T = void>
|
||||||
|
struct enable_if_c {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct enable_if_c<false, T> {};
|
||||||
|
|
||||||
|
template <class Cond, class T = void>
|
||||||
|
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||||
|
|
||||||
|
template <bool B, class T>
|
||||||
|
struct lazy_enable_if_c {
|
||||||
|
typedef typename T::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct lazy_enable_if_c<false, T> {};
|
||||||
|
|
||||||
|
template <class Cond, class T>
|
||||||
|
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
|
||||||
|
|
||||||
|
|
||||||
|
template <bool B, class T = void>
|
||||||
|
struct disable_if_c {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct disable_if_c<true, T> {};
|
||||||
|
|
||||||
|
template <class Cond, class T = void>
|
||||||
|
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||||
|
|
||||||
|
template <bool B, class T>
|
||||||
|
struct lazy_disable_if_c {
|
||||||
|
typedef typename T::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct lazy_disable_if_c<true, T> {};
|
||||||
|
|
||||||
|
template <class Cond, class T>
|
||||||
|
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace detail { typedef void enable_if_default_T; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct enable_if_does_not_work_on_this_compiler;
|
||||||
|
|
||||||
|
template <bool B, class T = detail::enable_if_default_T>
|
||||||
|
struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <bool B, class T = detail::enable_if_default_T>
|
||||||
|
struct disable_if_c : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <bool B, class T = detail::enable_if_default_T>
|
||||||
|
struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <bool B, class T = detail::enable_if_default_T>
|
||||||
|
struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <class Cond, class T = detail::enable_if_default_T>
|
||||||
|
struct enable_if : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <class Cond, class T = detail::enable_if_default_T>
|
||||||
|
struct disable_if : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <class Cond, class T = detail::enable_if_default_T>
|
||||||
|
struct lazy_enable_if : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <class Cond, class T = detail::enable_if_default_T>
|
||||||
|
struct lazy_disable_if : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_NO_SFINAE
|
||||||
|
|
||||||
|
#endif
|
65
include/boost/utility/result_of.hpp
Normal file
65
include/boost/utility/result_of.hpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// Boost result_of library
|
||||||
|
|
||||||
|
// Copyright Doug Gregor 2004. Use, modification and
|
||||||
|
// distribution is subject to the Boost Software License, Version
|
||||||
|
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// For more information, see http://www.boost.org/libs/utility
|
||||||
|
#ifndef BOOST_RESULT_OF_HPP
|
||||||
|
#define BOOST_RESULT_OF_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/type_traits/ice.hpp>
|
||||||
|
#include <boost/type.hpp>
|
||||||
|
#include <boost/preprocessor.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||||
|
|
||||||
|
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||||
|
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<typename F> struct result_of;
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||||
|
|
||||||
|
template<typename F, typename FArgs, bool HasResultType> struct get_result_of;
|
||||||
|
|
||||||
|
template<typename F, typename FArgs>
|
||||||
|
struct get_result_of<F, FArgs, true>
|
||||||
|
{
|
||||||
|
typedef typename F::result_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename F, typename FArgs>
|
||||||
|
struct get_result_of<F, FArgs, false>
|
||||||
|
{
|
||||||
|
typedef typename F::template result<FArgs>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
struct get_result_of<F, F(void), false>
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename F, typename FArgs>
|
||||||
|
struct result_of : get_result_of<F, FArgs, (has_result_type<F>::value)> {};
|
||||||
|
|
||||||
|
} // end namespace detail
|
||||||
|
|
||||||
|
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
|
||||||
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# error Your compiler cannot support class template result_of
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_RESULT_OF_HPP
|
82
include/boost/utility/value_init.hpp
Normal file
82
include/boost/utility/value_init.hpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// (C) 2002, Fernando Luis Cacciola Carballal.
|
||||||
|
//
|
||||||
|
// This material is provided "as is", with absolutely no warranty expressed
|
||||||
|
// or implied. Any use is at your own risk.
|
||||||
|
//
|
||||||
|
// Permission to use or copy this software for any purpose is hereby granted
|
||||||
|
// without fee, provided the above notices are retained on all copies.
|
||||||
|
// Permission to modify the code and to distribute modified code is granted,
|
||||||
|
// provided the above notices are retained, and a notice that the code was
|
||||||
|
// modified is included with the above copyright notice.
|
||||||
|
//
|
||||||
|
// 21 Ago 2002 (Created) Fernando Cacciola
|
||||||
|
//
|
||||||
|
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
|
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
|
|
||||||
|
#include "boost/detail/select_type.hpp"
|
||||||
|
#include "boost/type_traits/cv_traits.hpp"
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace vinit_detail {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class const_T_base
|
||||||
|
{
|
||||||
|
protected :
|
||||||
|
|
||||||
|
const_T_base() : x() {}
|
||||||
|
|
||||||
|
T x ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct non_const_T_base
|
||||||
|
{
|
||||||
|
protected :
|
||||||
|
|
||||||
|
non_const_T_base() : x() {}
|
||||||
|
|
||||||
|
mutable T x ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct select_base
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
detail::if_true< ::boost::is_const<T>::value >
|
||||||
|
::template then< const_T_base<T>, non_const_T_base<T> >::type type ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
} // namespace vinit_detail
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class value_initialized : private vinit_detail::select_base<T>::type
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
value_initialized() {}
|
||||||
|
|
||||||
|
operator T&() const { return this->x ; }
|
||||||
|
|
||||||
|
T& data() const { return this->x ; }
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T const& get ( value_initialized<T> const& x )
|
||||||
|
{
|
||||||
|
return x.data() ;
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
T& get ( value_initialized<T>& x )
|
||||||
|
{
|
||||||
|
return x.data() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
33
include/boost/utility_fwd.hpp
Normal file
33
include/boost/utility_fwd.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Boost utility_fwd.hpp header file ---------------------------------------//
|
||||||
|
|
||||||
|
// Copyright 2001, 2003 Boost.org. Use, modification, and distribution are
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||||
|
|
||||||
|
// See <http://www.boost.org/libs/utility/> for the library's home page.
|
||||||
|
|
||||||
|
#ifndef BOOST_UTILITY_FWD_HPP
|
||||||
|
#define BOOST_UTILITY_FWD_HPP
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// From <boost/utility/base_from_member.hpp> -------------------------------//
|
||||||
|
|
||||||
|
template < typename MemberType, int UniqueID = 0 >
|
||||||
|
class base_from_member;
|
||||||
|
|
||||||
|
|
||||||
|
// From <boost/noncopyable.hpp> --------------------------------------------//
|
||||||
|
|
||||||
|
class noncopyable;
|
||||||
|
|
||||||
|
// Also has a few function templates
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_UTILITY_FWD_HPP
|
@@ -1,61 +0,0 @@
|
|||||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
|
||||||
// distribute this software is granted provided this copyright notice appears
|
|
||||||
// in all copies. This software is provided "as is" without express or implied
|
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <functional>
|
|
||||||
#include <boost/iterator_adaptors.hpp>
|
|
||||||
|
|
||||||
int main(int, char*[])
|
|
||||||
{
|
|
||||||
char characters[] = "abcdefg";
|
|
||||||
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
|
|
||||||
char* pointers_to_chars[N]; // at the end.
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
pointers_to_chars[i] = &characters[i];
|
|
||||||
|
|
||||||
// Example of using indirect_iterator_generator
|
|
||||||
|
|
||||||
boost::indirect_iterator_generator<char**, char>::type
|
|
||||||
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
|
||||||
|
|
||||||
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Example of using indirect_iterator_pair_generator
|
|
||||||
|
|
||||||
typedef boost::indirect_iterator_pair_generator<char**,
|
|
||||||
char, char*, char&, const char*, const char&> PairGen;
|
|
||||||
|
|
||||||
char mutable_characters[N];
|
|
||||||
char* pointers_to_mutable_chars[N];
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
pointers_to_mutable_chars[i] = &mutable_characters[i];
|
|
||||||
|
|
||||||
PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
|
|
||||||
mutable_indirect_last(pointers_to_mutable_chars + N);
|
|
||||||
PairGen::const_iterator const_indirect_first(pointers_to_chars),
|
|
||||||
const_indirect_last(pointers_to_chars + N);
|
|
||||||
|
|
||||||
std::transform(const_indirect_first, const_indirect_last,
|
|
||||||
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
|
||||||
|
|
||||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
|
||||||
std::ostream_iterator<char>(std::cout, ","));
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Example of using make_indirect_iterator()
|
|
||||||
|
|
||||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
|
||||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
|
||||||
std::ostream_iterator<char>(std::cout, ","));
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
104
utility.htm
104
utility.htm
@@ -1,104 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
||||||
<title>Header boost/utility.hpp Documentation</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
|
||||||
|
|
||||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
|
|
||||||
<a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
|
|
||||||
|
|
||||||
<p>The entire contents of the header <code><a href="../../boost/utility.hpp"><boost/utility.hpp></a></code>
|
|
||||||
are in <code>namespace boost</code>.</p>
|
|
||||||
|
|
||||||
<h2>Contents</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Function templates <a href="#functions next">next() and prior()</a></li>
|
|
||||||
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
|
|
||||||
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
|
|
||||||
</ul>
|
|
||||||
<h2> <a name="functions next">Function</a> templates next() and prior()</h2>
|
|
||||||
|
|
||||||
<p>Certain data types, such as the C++ Standard Library's forward and
|
|
||||||
bidirectional iterators, do not provide addition and subtraction via operator+()
|
|
||||||
or operator-(). This means that non-modifying computation of the next or
|
|
||||||
prior value requires a temporary, even though operator++() or operator--() is
|
|
||||||
provided. It also means that writing code like <code>itr+1</code> inside a
|
|
||||||
template restricts the iterator category to random access iterators.</p>
|
|
||||||
|
|
||||||
<p>The next() and prior() functions provide a simple way around these problems:</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
|
|
||||||
<pre>template <class T>
|
|
||||||
T next(T x) { return ++x; }
|
|
||||||
|
|
||||||
template <class X>
|
|
||||||
T prior(T x) { return --x; }</pre>
|
|
||||||
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>Usage is simple:</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
|
|
||||||
<pre>const std::list<T>::iterator p = get_some_iterator();
|
|
||||||
const std::list<T>::iterator prev = boost::prior(p);</pre>
|
|
||||||
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
|
|
||||||
|
|
||||||
<h2><a name="Class noncopyable">Class noncopyable</a></h2>
|
|
||||||
|
|
||||||
<p>Class <strong>noncopyable</strong> is a base class. Derive your own class from <strong>noncopyable</strong>
|
|
||||||
when you want to prohibit copy construction and copy assignment.</p>
|
|
||||||
|
|
||||||
<p>Some objects, particularly those which hold complex resources like files or
|
|
||||||
network connections, have no sensible copy semantics. Sometimes there are
|
|
||||||
possible copy semantics, but these would be of very limited usefulness and be
|
|
||||||
very difficult to implement correctly. Sometimes you're implementing a class that doesn't need to be copied
|
|
||||||
just yet and you don't want to take the time to write the appropriate functions.
|
|
||||||
Deriving from <b> noncopyable</b> will prevent the otherwise implicitly-generated
|
|
||||||
functions (which don't have the proper semantics) from becoming a trap for other programmers.</p>
|
|
||||||
|
|
||||||
<p>The traditional way to deal with these is to declare a private copy constructor and copy assignment, and then
|
|
||||||
document why this is done. But deriving from <b>noncopyable</b> is simpler
|
|
||||||
and clearer, and doesn't require additional documentation.</p>
|
|
||||||
|
|
||||||
<p>The program <a href="noncopyable_test.cpp">noncopyable_test.cpp</a> can be
|
|
||||||
used to verify class <b>noncopyable</b> works as expected. It has have been run successfully under
|
|
||||||
GCC 2.95, Metrowerks
|
|
||||||
CodeWarrior 5.0, and Microsoft Visual C++ 6.0 sp 3.</p>
|
|
||||||
|
|
||||||
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
|
|
||||||
|
|
||||||
<h3>Example</h3>
|
|
||||||
<blockquote>
|
|
||||||
<pre>// inside one of your own headers ...
|
|
||||||
#include <boost/utility.hpp>
|
|
||||||
|
|
||||||
class ResourceLadenFileSystem : boost::noncopyable {
|
|
||||||
...</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<h3>Rationale</h3>
|
|
||||||
<p>Class noncopyable has protected constructor and destructor members to
|
|
||||||
emphasize that it is to be used only as a base class. Dave Abrahams notes
|
|
||||||
concern about the effect on compiler optimization of adding (even trivial inline)
|
|
||||||
destructor declarations. He says "Probably this concern is misplaced, because
|
|
||||||
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."</p>
|
|
||||||
<hr>
|
|
||||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
|
||||||
-->16 February, 2001<!--webbot bot="Timestamp" endspan i-checksum="40407"
|
|
||||||
-->
|
|
||||||
</p>
|
|
||||||
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
|
||||||
distribute this document is granted provided this copyright notice appears in
|
|
||||||
all copies. This document is provided "as is" without express or
|
|
||||||
implied warranty, and with no claim as to its suitability for any purpose.</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Reference in New Issue
Block a user